commit
878a875ff1
@ -0,0 +1,244 @@ |
||||
|
||||
import React from 'react' |
||||
import { ViewPlugin } from '@remixproject/engine-web' |
||||
import { PluginViewWrapper } from '@remix-ui/helper' |
||||
import { RemixAppManager } from '../../remixAppManager' |
||||
import { RemixUIGridView } from '@remix-ui/remix-ui-grid-view' |
||||
import { RemixUIGridSection } from '@remix-ui/remix-ui-grid-section' |
||||
import { RemixUIGridCell } from '@remix-ui/remix-ui-grid-cell' |
||||
import { ThemeKeys, ThemeObject } from '@microlink/react-json-view' |
||||
//@ts-ignore
|
||||
const _paq = (window._paq = window._paq || []) |
||||
|
||||
const profile = { |
||||
name: 'remixGuide', |
||||
displayName: 'Remix Guide', |
||||
description: 'Learn remix with videos', |
||||
location: 'mainPanel', |
||||
methods: ['showDetails'], |
||||
events: [] |
||||
} |
||||
|
||||
export class RemixGuidePlugin extends ViewPlugin { |
||||
dispatch: React.Dispatch<any> = () => { } |
||||
appManager: RemixAppManager |
||||
element: HTMLDivElement |
||||
payload: any |
||||
themeStyle: any |
||||
theme: ThemeKeys | ThemeObject |
||||
constructor(appManager: RemixAppManager) { |
||||
super(profile) |
||||
this.appManager = appManager |
||||
this.element = document.createElement('div') |
||||
this.element.setAttribute('id', 'remixGuideEl')
|
||||
} |
||||
|
||||
async onActivation() { |
||||
this.handleThemeChange() |
||||
await this.call('tabs', 'focus', 'remixGuide') |
||||
this.renderComponent() |
||||
_paq.push(['trackEvent', 'plugin', 'activated', 'remixGuide']) |
||||
} |
||||
|
||||
onDeactivation(): void { |
||||
} |
||||
|
||||
async showDetails(sentPayload: any) { |
||||
const contractName = Object.entries(sentPayload).find(([key, value]) => key) |
||||
await this.call('tabs', 'focus', 'remixGuide') |
||||
this.profile.displayName = `${contractName[0]}` |
||||
this.payload = sentPayload |
||||
const active = await this.call('theme', 'currentTheme') |
||||
|
||||
this.renderComponent() |
||||
} |
||||
|
||||
private handleThemeChange() { |
||||
this.on('theme', 'themeChanged', (theme: any) => { |
||||
|
||||
this.renderComponent() |
||||
}) |
||||
} |
||||
|
||||
setDispatch(dispatch: React.Dispatch<any>): void { |
||||
this.dispatch = dispatch |
||||
this.renderComponent() |
||||
} |
||||
render() { |
||||
return ( |
||||
<div className="bg-dark" id="remixGuide"> |
||||
<PluginViewWrapper plugin={this} /> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
renderComponent() { |
||||
this.dispatch({ |
||||
...this, |
||||
...this.payload, |
||||
themeStyle: this.themeStyle, |
||||
theme: this.theme |
||||
}) |
||||
} |
||||
|
||||
updateComponent(state: any) { |
||||
return ( |
||||
<RemixUIGridView |
||||
plugin={this} |
||||
styleList={""} |
||||
logo='/assets/img/YouTubeLogo.webp' |
||||
enableFilter={true} |
||||
showUntagged={true} |
||||
showPin={true} |
||||
tagList={[ |
||||
['beginner', 'danger'], |
||||
['advanced', 'warning'], |
||||
['AI', 'success'], |
||||
['plugins', 'secondary'], |
||||
['solidity', 'primary'], |
||||
['vyper', 'info'], |
||||
['L2', 'danger'] |
||||
]} |
||||
title='Remix Guide' |
||||
description="Streamlined access to categorized video tutorials for mastering Remix IDE. From fundamentals to advanced techniques, level up your development skills with ease." |
||||
//themeStyle={state.themeStyle}
|
||||
> |
||||
<RemixUIGridSection |
||||
plugin={this} |
||||
title='Basics' |
||||
hScrollable= {true} |
||||
> |
||||
<RemixUIGridCell |
||||
plugin={this} |
||||
title="first item" |
||||
tagList={['L2', 'AI']} |
||||
logo='/assets/img/soliditySurvey2023.webp' |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> |
||||
<RemixUIGridCell |
||||
plugin={this} |
||||
title="next" |
||||
pinned={true} |
||||
tagList={['L2', 'plugins']} |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> <RemixUIGridCell |
||||
plugin={this} |
||||
title="something" |
||||
pinned={false} |
||||
tagList={['solidity', 'plugins']} |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> |
||||
<RemixUIGridCell |
||||
plugin={this} |
||||
title="1" |
||||
tagList={['solidity']} |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> <RemixUIGridCell |
||||
plugin={this} |
||||
title="1" |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> |
||||
<RemixUIGridCell |
||||
plugin={this} |
||||
title="Something very very long" |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> <RemixUIGridCell |
||||
plugin={this} |
||||
title="1" |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> |
||||
<RemixUIGridCell |
||||
plugin={this} |
||||
title="1" |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> |
||||
<RemixUIGridCell |
||||
plugin={this} |
||||
title="1" |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> |
||||
<RemixUIGridCell |
||||
plugin={this} |
||||
title="1" |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> |
||||
</RemixUIGridSection> |
||||
<RemixUIGridSection |
||||
plugin={this} |
||||
title='Basics not scrollable' |
||||
hScrollable= {false} |
||||
> |
||||
<RemixUIGridCell |
||||
plugin={this} |
||||
title="first item" |
||||
logo='/assets/img/soliditySurvey2023.webp' |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> |
||||
<RemixUIGridCell |
||||
plugin={this} |
||||
title="next" |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> <RemixUIGridCell |
||||
plugin={this} |
||||
title="something" |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> |
||||
<RemixUIGridCell |
||||
plugin={this} |
||||
title="1" |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> <RemixUIGridCell |
||||
plugin={this} |
||||
title="1" |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> |
||||
<RemixUIGridCell |
||||
plugin={this} |
||||
title="1" |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> <RemixUIGridCell |
||||
plugin={this} |
||||
title="1" |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> |
||||
<RemixUIGridCell |
||||
plugin={this} |
||||
title="1" |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> |
||||
<RemixUIGridCell |
||||
plugin={this} |
||||
title="1" |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> |
||||
<RemixUIGridCell |
||||
plugin={this} |
||||
title="1" |
||||
> |
||||
<img src={'/assets/img/soliditySurvey2023.webp'} style={{height: '70px', width: '70px'}} alt=""></img> |
||||
</RemixUIGridCell> |
||||
</RemixUIGridSection> |
||||
</RemixUIGridView> |
||||
) |
||||
} |
||||
|
||||
} |
@ -0,0 +1,4 @@ |
||||
export * from './lib/remix-ui-grid-view' |
||||
export * from './lib/remix-ui-grid-section' |
||||
export * from './lib/remix-ui-grid-cell' |
||||
|
@ -0,0 +1,42 @@ |
||||
/* eslint-disable @typescript-eslint/no-unused-vars */ |
||||
import React from 'react' |
||||
import { useContext } from 'react' |
||||
import FiltersContext from ".././filtersContext" |
||||
|
||||
interface CustomCheckboxProps { |
||||
label: string |
||||
color?: string |
||||
} |
||||
|
||||
export const CustomCheckbox = (props: CustomCheckboxProps) => { |
||||
const filterCon = useContext(FiltersContext) |
||||
let textColor = props.color |
||||
let defChecked = true |
||||
if (filterCon.keyValueMap[props.label]) defChecked = filterCon.keyValueMap[props.label].enabled |
||||
if (!textColor || textColor == '') textColor = filterCon.keyValueMap[props.label].color |
||||
|
||||
return ( |
||||
<div id={textColor + props.label} className="h-80 mx-1 align-items-center custom-control custom-checkbox" style={{minWidth: '4rem'}}> |
||||
<input |
||||
className="custom-control-input" |
||||
id={"GVCheckbox" + props.label} |
||||
defaultChecked={defChecked} |
||||
onChange={e => { |
||||
if (props.label == 'no tag') |
||||
filterCon.showUntagged = ! filterCon.showUntagged |
||||
else filterCon.updateValue(props.label, e.target.checked, textColor)}} |
||||
type="checkbox" |
||||
/> |
||||
<label |
||||
className={"form-check-label custom-control-label text-nowrap text-" + textColor} |
||||
style={{ paddingTop: '0.125rem' }} |
||||
htmlFor={"GVCheckbox" + props.label} |
||||
data-id={"GVCheckboxLabel" + props.label} |
||||
> |
||||
{ props.label } |
||||
</label> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default CustomCheckbox |
@ -0,0 +1,18 @@ |
||||
import React, { createContext, useState, useContext } from 'react'; |
||||
|
||||
interface FilterContextType { |
||||
showUntagged: boolean |
||||
showPin: boolean |
||||
keyValueMap: Record<string, { enabled: boolean; color: string; }>; |
||||
updateValue: (key: string, enabled: boolean, color: string) => void |
||||
addValue: (key: string, enabled: boolean, color: string) => void |
||||
} |
||||
const FiltersContext = createContext<FilterContextType>({ |
||||
showUntagged: false, |
||||
showPin: false, |
||||
keyValueMap: {}, |
||||
updateValue: () => {}, |
||||
addValue: () => {}, |
||||
}); |
||||
|
||||
export default FiltersContext |
@ -0,0 +1,46 @@ |
||||
.remixui_grid_cell { |
||||
font-weight: normal; |
||||
} |
||||
|
||||
.remixui_grid_cell_container { |
||||
width: fit-content; |
||||
} |
||||
|
||||
.remixui_grid_cell_title{ |
||||
font-size: 0.8rem; |
||||
font-style: italic; |
||||
} |
||||
|
||||
.remixui_grid_cell_btn { |
||||
width: 32px; |
||||
} |
||||
|
||||
.remixui_grid_cell_logo { |
||||
width: 3rem; |
||||
height: 3rem; |
||||
} |
||||
|
||||
.remixui_grid_cell_pin:focus { |
||||
outline: none; |
||||
} |
||||
.remixui_grid_cell_pin { |
||||
width: 1rem; |
||||
height: 1rem; |
||||
position: relative; |
||||
right: 1rem; |
||||
top: -0.5rem; |
||||
background: transparent; |
||||
} |
||||
|
||||
.remixui_grid_cell_tags { |
||||
position: relative; |
||||
right: 1rem; |
||||
top: 0.1rem; |
||||
} |
||||
|
||||
.remixui_grid_cell_tag { |
||||
font-size: x-small; |
||||
font-weight: bolder; |
||||
width: 0.4rem; |
||||
height: 1.2rem; |
||||
} |
@ -0,0 +1,86 @@ |
||||
import React, {useState, useEffect, useContext, useRef, ReactNode} from 'react' // eslint-disable-line
|
||||
|
||||
import './remix-ui-grid-cell.css' |
||||
import FiltersContext from "./filtersContext" |
||||
import { CustomTooltip } from '@remix-ui/helper' |
||||
|
||||
|
||||
declare global { |
||||
interface Window { |
||||
_paq: any |
||||
} |
||||
} |
||||
const _paq = window._paq = window._paq || [] |
||||
|
||||
interface RemixUIGridCellProps { |
||||
plugin: any |
||||
pinned?: boolean |
||||
pinStateCallback?: any |
||||
logo?: string |
||||
title?: string
|
||||
tagList?: string[] // max 8, others will be ignored
|
||||
classList?: string |
||||
styleList?: any |
||||
children?: ReactNode |
||||
} |
||||
|
||||
export const RemixUIGridCell = (props: RemixUIGridCellProps) => { |
||||
const filterCon = useContext(FiltersContext) |
||||
const [anyEnabled, setAnyEnabled] = useState(false) |
||||
const [pinned, setPinned] = useState<boolean>(props.pinned) |
||||
|
||||
useEffect(() => { |
||||
if (props.tagList) setAnyEnabled(props.tagList.some((key) => filterCon.keyValueMap[key]?.enabled)) |
||||
else setAnyEnabled(filterCon.showUntagged)
|
||||
}, [filterCon, props.tagList]) |
||||
|
||||
return ( |
||||
<div className='mr-2 mt-3'> |
||||
{ anyEnabled && <div className='d-flex flex-grid'> |
||||
<div className={"d-flex mx-0 p-2 bg-light border border-secondary remixui_grid_cell_container " + props.classList || ''} data-id={"remixUIGS" + props.title}> |
||||
<div className="d-flex remixui_grid_cell flex-column"> |
||||
<div className='d-flex flex-row pb-1 align-items-end' style={{width: '8rem', height: '1rem'}}> |
||||
{ props.logo && <img className='remixui_grid_view_logo mr-1' src={props.logo} style={{width: '1rem', height: '1rem'}}/> } |
||||
{ props.title && <label |
||||
className='m-0 p-0 align-items-left' |
||||
style={{overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', fontSize: 'xx-small'}} |
||||
> |
||||
{ props.title } |
||||
</label> } |
||||
</div> |
||||
{ props.children } |
||||
</div> |
||||
</div> |
||||
{ filterCon.showPin && <button |
||||
className={`${pinned ? 'fa-duotone' : 'fa-light'}` + ` fa-map-pin text-info border-0 mb-0 remixui_grid_cell_pin`} |
||||
onClick={() => { |
||||
setPinned(!pinned) |
||||
props.pinStateCallback() |
||||
}} |
||||
></button>} |
||||
{ props.tagList && <div className='d-flex flex-column align-items-begin remixui_grid_cell_tags'> |
||||
{ Object.keys(props.tagList).map((key) => ( |
||||
filterCon.keyValueMap[props.tagList[key]].enabled && ( |
||||
<CustomTooltip |
||||
placement="right" |
||||
tooltipId="pluginManagerInactiveTitleLinkToDoc" |
||||
tooltipClasses="text-nowrap" |
||||
tooltipText={props.tagList[key]} |
||||
> |
||||
<span key={props.tagList[key]} |
||||
className={'remixui_grid_cell_tag bg-' + filterCon.keyValueMap[props.tagList[key]].color} |
||||
> |
||||
</span> |
||||
</CustomTooltip> |
||||
) |
||||
)) } |
||||
</div> } |
||||
{ !props.tagList && <span |
||||
className={'remixui_grid_cell_tags'}> |
||||
</span> } |
||||
</div> } |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default RemixUIGridCell |
@ -0,0 +1,26 @@ |
||||
.remixui_grid_section { |
||||
font-weight: normal; |
||||
} |
||||
|
||||
.remixui_grid_section_container { |
||||
width: fit-content; |
||||
} |
||||
|
||||
.remixui_grid_section_title{ |
||||
font-size: 0.8rem; |
||||
font-style: italic; |
||||
} |
||||
|
||||
.remixui_grid_section_btn { |
||||
width: 32px; |
||||
} |
||||
|
||||
.remixui_grid_section_logo { |
||||
width: 3rem; |
||||
height: 3rem; |
||||
} |
||||
|
||||
* { |
||||
scrollbar-width: thin; |
||||
scrollbar-color: var(--bg-dark) var(--bg-light); |
||||
} |
@ -0,0 +1,38 @@ |
||||
import React, {useState, useEffect, useContext, useRef, ReactNode} from 'react' // eslint-disable-line
|
||||
|
||||
import './remix-ui-grid-section.css' |
||||
|
||||
declare global { |
||||
interface Window { |
||||
_paq: any |
||||
} |
||||
} |
||||
const _paq = window._paq = window._paq || [] |
||||
|
||||
interface RemixUIGridSectionProps { |
||||
plugin: any |
||||
title?: string |
||||
hScrollable: boolean |
||||
classList?: string |
||||
styleList?: any |
||||
children?: ReactNode |
||||
} |
||||
|
||||
export const RemixUIGridSection = (props: RemixUIGridSectionProps) => { |
||||
return ( |
||||
<div |
||||
className={`d-flex px-4 py-2 flex-column w-100 remixui_grid_section_container ${props.classList}`} |
||||
data-id={"remixUIGS" + props.title} |
||||
style={{ overflowX: 'auto' }} |
||||
> |
||||
<div className="d-flex flex-column w-100 remixui_grid_section"> |
||||
{ props.title && <h6 className='mt-1 mb-0 align-items-left '>{ props.title }</h6> } |
||||
<div className={(props.hScrollable) ? `d-flex flex-row pb-2 overflow-auto` : `d-flex flex-wrap`}> |
||||
{ props.children } |
||||
</div> |
||||
</div> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default RemixUIGridSection |
@ -0,0 +1,25 @@ |
||||
.remixui_grid_view { |
||||
font-weight: normal; |
||||
} |
||||
|
||||
.remixui_grid_view_container { |
||||
overflow: auto; |
||||
} |
||||
|
||||
.remixui_grid_view_title{ |
||||
font-size: 0.8rem; |
||||
font-style: italic; |
||||
} |
||||
|
||||
.remixui_grid_view_btn { |
||||
width: 32px; |
||||
} |
||||
|
||||
.remixui_grid_view_logo { |
||||
width: 3rem; |
||||
height: 3rem; |
||||
} |
||||
|
||||
.remixui_grid_view_titlebar { |
||||
min-width: max-content; |
||||
} |
@ -0,0 +1,147 @@ |
||||
import React, {useState, useEffect, useContext, useRef, ReactNode} from 'react' // eslint-disable-line
|
||||
|
||||
import './remix-ui-grid-view.css' |
||||
import {ThemeContext, themes} from './themeContext' |
||||
import CustomCheckbox from './components/customCheckbox' |
||||
import FiltersContext from "./filtersContext" |
||||
|
||||
declare global { |
||||
interface Window { |
||||
_paq: any |
||||
} |
||||
} |
||||
const _paq = window._paq = window._paq || [] |
||||
|
||||
interface RemixUIGridViewProps { |
||||
plugin: any |
||||
logo?: string |
||||
title?: string |
||||
enableFilter?: boolean |
||||
tagList?: [string, string][] // max 8, others will be ignored
|
||||
showUntagged?: boolean |
||||
showPin?: boolean |
||||
classList?: string |
||||
styleList?: any |
||||
description?: string |
||||
children?: ReactNode |
||||
} |
||||
|
||||
export const RemixUIGridView = (props: RemixUIGridViewProps) => { |
||||
const [keyValueMap, setKeyValueMap] = useState<Record<string, { enabled: boolean; color: string; }>>({}); |
||||
|
||||
const showUntagged = props.showUntagged || false |
||||
const showPin = props.showPin || false |
||||
const updateValue = (key: string, enabled: boolean, color?: string) => { |
||||
if (!color || color === '') color = setKeyValueMap[key].color |
||||
setKeyValueMap((prevMap) => ({ |
||||
...prevMap, |
||||
[key]: {color, enabled}, |
||||
})) |
||||
} |
||||
|
||||
const addValue = (key: string, enabled: boolean, color: string) => { |
||||
// Check if the key already exists, if so, do not add
|
||||
if (key in keyValueMap) { |
||||
return |
||||
} |
||||
|
||||
// Add the new key-value pair
|
||||
setKeyValueMap((prevMap) => ({ |
||||
...prevMap, |
||||
[key]: { enabled, color }, |
||||
})) |
||||
} |
||||
|
||||
const {plugin} = props.plugin |
||||
const searchInputRef = useRef(null) |
||||
|
||||
const [state, setState] = useState<{ |
||||
themeQuality: {filter: string; name: string} |
||||
}>({ |
||||
themeQuality: themes.light |
||||
}) |
||||
|
||||
// Initialize filters context with data from props
|
||||
useEffect(() => { |
||||
if (props.tagList && Array.isArray(props.tagList)) { |
||||
const initialKeyValueMap: Record<string, { enabled: boolean; color: string; }> = {}; |
||||
|
||||
// Limit to first 8 elements, ignoring the rest
|
||||
for (let i = 0; i < props.tagList.length; i++) { |
||||
const [key, color] = props.tagList[i] |
||||
initialKeyValueMap[key] = { enabled: true, color }
|
||||
} |
||||
if (showUntagged) initialKeyValueMap['no tag'] = { enabled: true, color: 'primary' }
|
||||
setKeyValueMap(initialKeyValueMap) |
||||
} |
||||
}, []) |
||||
|
||||
useEffect(() => { |
||||
plugin?.call('theme', 'currentTheme').then((theme) => { |
||||
// update theme quality. To be used for for images
|
||||
setState((prevState) => { |
||||
return { |
||||
...prevState, |
||||
themeQuality: theme.quality === 'dark' ? themes.dark : themes.light |
||||
} |
||||
}) |
||||
}) |
||||
plugin?.on('theme', 'themeChanged', (theme) => { |
||||
// update theme quality. To be used for for images
|
||||
setState((prevState) => { |
||||
return { |
||||
...prevState, |
||||
themeQuality: theme.quality === 'dark' ? themes.dark : themes.light |
||||
} |
||||
}) |
||||
}) |
||||
}, [plugin]) |
||||
|
||||
return ( |
||||
<FiltersContext.Provider value={{ showUntagged, showPin, keyValueMap, updateValue, addValue }}> |
||||
<div className={"d-flex flex-column bg-dark w-100 h-100 remixui_grid_view_container " + props.classList || ''} data-id="remixUIGV"> |
||||
<ThemeContext.Provider value={state.themeQuality}> |
||||
<div className="d-flex flex-column w-100 remixui_grid_view"> |
||||
<div className='d-flex p-4 bg-light flex-column remixui_grid_view_titlebar'> |
||||
<div className='d-flex flex-row align-items-center mb-2'> |
||||
{ props.logo && <img className='remixui_grid_view_logo mr-2' src={props.logo} /> } |
||||
{ props.title && <h3 className='mb-0'>{ props.title }</h3> } |
||||
</div> |
||||
{ props.description && <div className='pb-3 remixui_grid_view_title'>{ props.description }</div> } |
||||
{ props.enableFilter && <div className='d-flex flex-row'> |
||||
<div className="d-flex flex-row pr-2 pb-1 align-items-center justify-content-between"> |
||||
<div className='d-flex' id="GVFilter"> |
||||
<button |
||||
className="remixui_grid_view_btn text-secondary form-control bg-light border d-flex align-items-center p-2 justify-content-center fas fa-filter bg-light" |
||||
onClick={(e) => { |
||||
_paq.push(['trackEvent', 'GridView' + props.title ? props.title : '', 'filter', searchInputRef.current.value]) |
||||
//setstate
|
||||
}} |
||||
></button> |
||||
<input |
||||
ref={searchInputRef} |
||||
type="text" |
||||
style={{minWidth: '100px'}} |
||||
className="border form-control border-right-0 mr-4" |
||||
id="GVFilterInput" |
||||
placeholder={"Filter the list"} |
||||
data-id="RemixGVFilterInput" |
||||
/> |
||||
</div> |
||||
<div className='d-flex flex-row'> |
||||
{ Object.keys(keyValueMap).map((key) => ( |
||||
<CustomCheckbox label={key} /> |
||||
)) } |
||||
</div> |
||||
</div> |
||||
</div> } |
||||
</div> |
||||
{ props.children } |
||||
</div> |
||||
</ThemeContext.Provider> |
||||
</div> |
||||
</FiltersContext.Provider> |
||||
) |
||||
} |
||||
|
||||
export default RemixUIGridView |
@ -0,0 +1,16 @@ |
||||
import React from 'react' // eslint-disable-line
|
||||
|
||||
export const themes = { |
||||
light: { |
||||
filter: 'invert(0)', |
||||
name: 'light' |
||||
}, |
||||
dark: { |
||||
filter: 'invert(1)', |
||||
name: 'dark' |
||||
} |
||||
} |
||||
|
||||
export const ThemeContext = React.createContext( |
||||
themes.dark // default value
|
||||
) |
Loading…
Reference in new issue