wip: work on editor
This commit is contained in:
parent
30ae7b09da
commit
c8b989afcb
16 changed files with 345 additions and 215 deletions
|
@ -105,6 +105,7 @@ packageJson:
|
|||
"./components/Table": "./components/Table/index.mjs"
|
||||
"./components/Time": "./components/Time/index.mjs"
|
||||
"./components/Uuid": "./components/Uuid/index.mjs"
|
||||
"./components/Ux": "./components/Ux/index.mjs"
|
||||
"./components/Yaml": "./components/Yaml/index.mjs"
|
||||
"./components/Xray": "./components/Xray/index.mjs"
|
||||
# Context
|
||||
|
|
131
packages/react/components/Editor/components/Flag.mjs
Normal file
131
packages/react/components/Editor/components/Flag.mjs
Normal file
|
@ -0,0 +1,131 @@
|
|||
import React from 'react'
|
||||
import mustache from 'mustache'
|
||||
import { defaultConfig } from '../config/index.mjs'
|
||||
import { flattenFlags } from '../lib/index.mjs'
|
||||
import {
|
||||
ChatIcon,
|
||||
ErrorIcon,
|
||||
ExpandIcon,
|
||||
DocsIcon,
|
||||
FixmeIcon,
|
||||
FlagIcon,
|
||||
OptionsIcon,
|
||||
TipIcon,
|
||||
WarningIcon,
|
||||
WrenchIcon,
|
||||
} from '@freesewing/react/components/Icon'
|
||||
import { SubAccordion } from './Accordion.mjs'
|
||||
|
||||
/*
|
||||
* Helper object to look up flag icons
|
||||
*/
|
||||
const flagIcons = {
|
||||
error: ErrorIcon,
|
||||
expand: ExpandIcon,
|
||||
fixme: WrenchIcon,
|
||||
info: DocsIcon,
|
||||
note: ChatIcon,
|
||||
otions: OptionsIcon,
|
||||
tip: TipIcon,
|
||||
warning: WarningIcon,
|
||||
}
|
||||
|
||||
export const FlagTypeIcon = ({ type, className = 'tw-w-6 tw-h-6' }) => {
|
||||
const Icon = flagIcons[type] || FixmeIcon
|
||||
|
||||
return <Icon className={className} />
|
||||
}
|
||||
|
||||
export const Flag = ({ data, handleUpdate }) => {
|
||||
const btnIcon = data.suggest?.icon ? (
|
||||
<FlagTypeIcon type={data.suggest.icon} className="tw-w-5 tw-h-6 sm:tw-w-6 tw-h-6" />
|
||||
) : null
|
||||
|
||||
const button =
|
||||
data.suggest?.text && data.suggest?.update ? (
|
||||
<button
|
||||
className={`tw-btn tw-btn-secondary tw-btn-outline tw-flex tw-flex-row tw-items-center ${
|
||||
btnIcon ? 'tw-gap-6' : ''
|
||||
}`}
|
||||
onClick={() => handleUpdate(data.suggest.update)}
|
||||
>
|
||||
{btnIcon}
|
||||
{data.suggest.text}
|
||||
</button>
|
||||
) : null
|
||||
|
||||
const desc = data.replace ? mustache.render(data.desc, data.replace) : data.desc
|
||||
const notes = data.notes
|
||||
? Array.isArray(data.notes)
|
||||
? '\n\n' +
|
||||
data.notes
|
||||
.map((note) => (data.replace ? mustache.render(note, data.replace) : note))
|
||||
.join('\n\n')
|
||||
: '\n\n' + (data.replace ? mustache.render(data.notes, data.replace) : data.notes)
|
||||
: null
|
||||
|
||||
return (
|
||||
<div className="tw-flex tw-flex-col tw-gap-2 tw-items-start">
|
||||
<div className="first:tw-mt-0 tw-grow md flag">
|
||||
<pre>{desc}</pre>
|
||||
<pre>{notes}</pre>
|
||||
</div>
|
||||
{button ? (
|
||||
<div className="tw-mt-2 tw-w-full tw-flex tw-flex-row tw-justify-end">{button}</div>
|
||||
) : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export const FlagsAccordionTitle = ({ flags }) => {
|
||||
const flagList = flattenFlags(flags)
|
||||
|
||||
if (Object.keys(flagList).length < 1) return null
|
||||
|
||||
return (
|
||||
<>
|
||||
<h5 className="tw-flex tw-flex-row tw-gap-2 tw-items-center tw-justify-between tw-w-full">
|
||||
<span className="tw-text-left">Flags ({Object.keys(flagList).length})</span>
|
||||
<FlagTypeIcon className="tw-w-8 tw-h-8" />
|
||||
</h5>
|
||||
<p className="tw-text-left">
|
||||
{Object.keys(flagList).length > 1
|
||||
? 'Some issues about your current pattern need your attention.'
|
||||
: 'A specific issue about your current pattern needs your attention.'}
|
||||
</p>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export const FlagsAccordionEntries = ({ flags, update }) => {
|
||||
const flagList = flattenFlags(flags)
|
||||
|
||||
if (Object.keys(flagList).length < 1) return null
|
||||
|
||||
const handleUpdate = (config) => {
|
||||
if (config.settings) update.settings(...config.settings)
|
||||
if (config.ui) update.ui(...config.settings)
|
||||
}
|
||||
|
||||
return (
|
||||
<SubAccordion
|
||||
items={Object.entries(flagList).map(([key, flag], i) => {
|
||||
const title = flag.replace ? mustache.render(flag.title, flag.replace) : flag.title
|
||||
|
||||
return [
|
||||
<div className="tw-w-full tw-flex tw-flex-row tw-gap2 tw-justify-between" key={i}>
|
||||
<div className="tw-flex tw-flex-row tw-items-center tw-gap-2">
|
||||
<div className="tw-no-shrink">
|
||||
<FlagIcon type={flag.type} />
|
||||
</div>
|
||||
<span className="tw-font-medium tw-text-left">{title}</span>
|
||||
</div>
|
||||
<span className="tw-uppercase tw-font-bold">{flag.type}</span>
|
||||
</div>,
|
||||
<Flag key={key} data={flag} handleUpdate={handleUpdate} />,
|
||||
key,
|
||||
]
|
||||
})}
|
||||
/>
|
||||
)
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
// Dependencies
|
||||
import { missingMeasurements } from '../lib/index.mjs'
|
||||
import { missingMeasurements, flattenFlags } from '../lib/index.mjs'
|
||||
// Hooks
|
||||
import React, { useState } from 'react'
|
||||
// Components
|
||||
|
@ -7,9 +7,29 @@ import { Null } from './Null.mjs'
|
|||
import { AsideViewMenuSpacer } from './AsideViewMenu.mjs'
|
||||
import { ViewIcon, viewLabels } from './views/index.mjs'
|
||||
import { Tooltip } from './Tooltip.mjs'
|
||||
import { ErrorIcon } from '@freesewing/react/components/Icon'
|
||||
import {
|
||||
CircleIcon,
|
||||
DetailIcon,
|
||||
ErrorIcon,
|
||||
ExpandIcon,
|
||||
ExportIcon,
|
||||
KioskIcon,
|
||||
MenuIcon,
|
||||
PaperlessIcon,
|
||||
ResetAllIcon,
|
||||
RocketIcon,
|
||||
RotateIcon,
|
||||
SaIcon,
|
||||
SaveAsIcon,
|
||||
SaveIcon,
|
||||
TrashIcon,
|
||||
UndoIcon,
|
||||
UnitsIcon,
|
||||
} from '@freesewing/react/components/Icon'
|
||||
import { DesignOptionsMenu } from './menus/DesignOptionsMenu.mjs'
|
||||
import { CoreSettingsMenu } from './menus/CoreSettingsMenu.mjs'
|
||||
import { UiPreferencesMenu } from './menus/UiPreferencesMenu.mjs'
|
||||
import { FlagsAccordionEntries } from './Flag.mjs'
|
||||
|
||||
export const HeaderMenuAllViews = ({ config, state, update, open, setOpen }) => (
|
||||
<HeaderMenuViewMenu {...{ config, state, update, open, setOpen }} />
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import React, { useState, useMemo, useCallback, forwardRef, useContext } from 'react'
|
||||
import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch'
|
||||
import { Pattern } from '@freesewing/react/components/Pattern'
|
||||
|
||||
/*
|
||||
* A pattern you can pan and zoom
|
||||
*/
|
||||
export const ZoomablePattern = forwardRef(function ZoomablePatternRef(props, ref) {
|
||||
const { renderProps, Swizzled, rotate } = props
|
||||
const { renderProps, rotate } = props
|
||||
const { onTransformed, setZoomFunctions } = useContext(ZoomContext)
|
||||
|
||||
return (
|
||||
|
@ -24,9 +25,8 @@ export const ZoomablePattern = forwardRef(function ZoomablePatternRef(props, ref
|
|||
id="pan-zoom-pattern"
|
||||
>
|
||||
{props.children || (
|
||||
<Swizzled.components.Pattern
|
||||
<Pattern
|
||||
{...{ renderProps }}
|
||||
t={Swizzled.methods.t}
|
||||
ref={ref}
|
||||
className={`freesewing pattern w-full ${rotate ? '-rotate-90' : ''}`}
|
||||
/>
|
||||
|
|
|
@ -5,6 +5,22 @@ import {
|
|||
menuCoreSettingsSammHandler,
|
||||
menuCoreSettingsStructure,
|
||||
} from '../../lib/index.mjs'
|
||||
import {
|
||||
MenuBoolInput,
|
||||
MenuListInput,
|
||||
MenuMmInput,
|
||||
MenuOnlySettingInput,
|
||||
MenuSliderInput,
|
||||
} from './Input.mjs'
|
||||
import {
|
||||
//MenuBoolValue,
|
||||
MenuListValue,
|
||||
MenuMmValue,
|
||||
MenuOnlySettingValue,
|
||||
MenuScaleSettingValue,
|
||||
} from './Value.mjs'
|
||||
import { MenuItemGroup } from './Container.mjs'
|
||||
import { SettingsIcon } from '@freesewing/react/components/Icon'
|
||||
|
||||
/**
|
||||
* The core settings menu
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
// Depdendencies
|
||||
import React from 'react'
|
||||
import { menuUiPreferencesStructure } from '../../lib/index.mjs'
|
||||
// Components
|
||||
import { MenuUxSettingInput, MenuListInput } from './Input.mjs'
|
||||
import { MenuListValue } from './Value.mjs'
|
||||
import { MenuItemGroup } from './Container.mjs'
|
||||
import { Ux } from '@freesewing/react/components/Ux'
|
||||
|
||||
export const UiPreferencesMenu = ({ update, state, Design }) => {
|
||||
console.log(state)
|
||||
const structure = menuUiPreferencesStructure()
|
||||
|
||||
const drillProps = { Design, state, update }
|
||||
const inputs = {
|
||||
ux: (props) => <MenuUxSettingInput {...drillProps} {...props} />,
|
||||
aside: (props) => <MenuListInput {...drillProps} {...props} />,
|
||||
kiosk: (props) => <MenuListInput {...drillProps} {...props} />,
|
||||
rotate: (props) => <MenuListInput {...drillProps} {...props} />,
|
||||
renderer: (props) => <MenuListInput {...drillProps} {...props} />,
|
||||
}
|
||||
const values = {
|
||||
ux: (props) => <Ux ux={state.ui.ux} {...props} />,
|
||||
aside: MenuListValue,
|
||||
kiosk: MenuListValue,
|
||||
rotate: MenuListValue,
|
||||
renderer: MenuListValue,
|
||||
}
|
||||
|
||||
return (
|
||||
<MenuItemGroup
|
||||
{...{
|
||||
structure,
|
||||
ux: state.ui?.ux,
|
||||
currentValues: state.ui || {},
|
||||
Item: (props) => (
|
||||
<UiPreference updateHandler={update} {...{ inputs, values, Design }} {...props} />
|
||||
),
|
||||
isFirst: true,
|
||||
name: 'pe:uiPreferences',
|
||||
language: state.locale,
|
||||
passProps: {
|
||||
ux: state.ui?.ux,
|
||||
settings: state.settings,
|
||||
patternConfig: Design.patternConfig,
|
||||
},
|
||||
updateHandler: update.ui,
|
||||
isDesignOptionsGroup: false,
|
||||
state,
|
||||
Design,
|
||||
inputs,
|
||||
values,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export const UiPreference = ({ name, ux, ...rest }) => (
|
||||
<MenuItem {...rest} name={name} allowToggle={!['ux', 'view'].includes(name) && ux > 3} ux={ux} />
|
||||
)
|
|
@ -1,34 +1,62 @@
|
|||
import React from 'react'
|
||||
import { mergeOptions } from '@freesewing/core'
|
||||
import { formatMm } from '@freesewing/utils'
|
||||
import { BoolYesIcon, BoolNoIcon } from '@freesewing/react/components/Icon'
|
||||
|
||||
/** Displays that constant values are not implemented in the front end */
|
||||
/**
|
||||
* this method is here to capture deprecated use of the translation method
|
||||
*
|
||||
* @param {string} key - The translation key
|
||||
* @retunr {string} key - Returns the key as-is
|
||||
*/
|
||||
const t = (key) => {
|
||||
console.log('FIXME: t method called in react/components/Editor/components/menus/Value.mjs')
|
||||
return key
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays that constant values are not implemented in the front end
|
||||
*/
|
||||
export const MenuConstantOptionValue = () => (
|
||||
<span className="text-error">FIXME: No ConstantOptionvalue implemented</span>
|
||||
)
|
||||
|
||||
/** Displays a count value*/
|
||||
/**
|
||||
* Displays a count value
|
||||
*
|
||||
* @param {object} config - The option config
|
||||
* @param {number} current - The current (count) value
|
||||
* @param {bool} changed - Whether or not the value is non-default
|
||||
*/
|
||||
export const MenuCountOptionValue = ({ config, current, changed }) => (
|
||||
<MenuShowValue {...{ current, changed, dflt: config.count }} />
|
||||
)
|
||||
|
||||
/** Displays a degree value */
|
||||
/**
|
||||
* Displays a degree value
|
||||
*
|
||||
* @param {object} config - The option config
|
||||
* @param {number} current - The current (count) value
|
||||
* @param {bool} changed - Whether or not the value is non-default
|
||||
*/
|
||||
export const MenuDegOptionValue = ({ config, current, changed }) => (
|
||||
<MenuHighlightValue changed={changed}> {changed ? current : config.deg}°</MenuHighlightValue>
|
||||
)
|
||||
|
||||
/**
|
||||
* A component to highlight a changed value
|
||||
* @param {Boolean} changed - Whether the value is changed or not
|
||||
*
|
||||
* @param {Boolean} changed - Whether the value is non-default
|
||||
* @param {Function} children - The React children
|
||||
*/
|
||||
export const MenuHighlightValue = ({ changed, children }) => (
|
||||
<span className={changed ? 'text-accent' : ''}> {children} </span>
|
||||
)
|
||||
|
||||
/** Displays a list option value */
|
||||
export const MenuListOptionValue = (props) => (
|
||||
<MenuListValue {...props} t={(input) => 'fixme handle option translation'} />
|
||||
)
|
||||
/**
|
||||
* Displays a list option value
|
||||
*/
|
||||
export const MenuListOptionValue = (props) => <MenuListValue {...props} t={t} />
|
||||
|
||||
/**
|
||||
* Displays the correct, translated value for a list
|
||||
|
@ -51,20 +79,26 @@ export const MenuListValue = ({ current, config, changed }) => {
|
|||
else if (val) key = <BoolYesIcon />
|
||||
else key = <BoolNoIcon />
|
||||
|
||||
const translated = config.doNotTranslate || typeof key !== 'string' ? key : t(key)
|
||||
const translated = config.doNotTranslate || key
|
||||
|
||||
return <MenuHighlightValue changed={changed}>{translated}</MenuHighlightValue>
|
||||
}
|
||||
|
||||
/** Displays the corrent, translated value for a boolean */
|
||||
/**
|
||||
* Displays the corrent, translated value for a boolean
|
||||
*/
|
||||
export const MenuBoolValue = MenuListOptionValue
|
||||
|
||||
/** Displays the MmOptions are not supported */
|
||||
/**
|
||||
* Displays the MmOptions are not supported
|
||||
*/
|
||||
export const MenuMmOptionValue = () => (
|
||||
<span className="text-error">FIXME: No Mm Options are not supported</span>
|
||||
)
|
||||
|
||||
/** Displays a formated mm value based on the current units */
|
||||
/**
|
||||
* Displays a formated mm value based on the current units
|
||||
*/
|
||||
export const MenuMmValue = ({ current, config, units, changed }) => (
|
||||
<MenuHighlightValue changed={changed}>
|
||||
<span
|
||||
|
@ -75,7 +109,8 @@ export const MenuMmValue = ({ current, config, units, changed }) => (
|
|||
</MenuHighlightValue>
|
||||
)
|
||||
|
||||
/** Displays the current percentage value, and the absolute value if configured
|
||||
/**
|
||||
* Displays the current percentage value, and the absolute value if configured
|
||||
*
|
||||
**************************************************************************
|
||||
* SliderIcon Title THIS *
|
||||
|
@ -83,7 +118,7 @@ export const MenuMmValue = ({ current, config, units, changed }) => (
|
|||
* ----------------------0----------------------------------------------- *
|
||||
* msg PencilIcon ResetIcon *
|
||||
**************************************************************************
|
||||
* */
|
||||
*/
|
||||
export const MenuPctOptionValue = ({ config, current, settings, changed, patternConfig }) => {
|
||||
const val = changed ? current : config.pct / 100
|
||||
|
||||
|
@ -101,6 +136,7 @@ export const MenuPctOptionValue = ({ config, current, settings, changed, pattern
|
|||
|
||||
/**
|
||||
* A component to display a value, highligting it if it changed
|
||||
*
|
||||
* @param {Number|String|Boolean} options.current - The current value, if it has been changed
|
||||
* @param {Number|String|Boolean} options.dflt - The default value
|
||||
* @param {Boolean} options.changed - Has the value been changed?
|
||||
|
@ -109,10 +145,24 @@ export const MenuShowValue = ({ current, dflt, changed }) => {
|
|||
return <MenuHighlightValue changed={changed}> {changed ? current : dflt} </MenuHighlightValue>
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the value for core's scale setting
|
||||
*
|
||||
* @param {object} config - The option config
|
||||
* @param {number} current - The current (count) value
|
||||
* @param {bool} changed - Whether or not the value is non-default
|
||||
*/
|
||||
export const MenuScaleSettingValue = ({ current, config, changed }) => (
|
||||
<MenuHighlightValue current={current} dflt={config.dflt} changed={changed} />
|
||||
)
|
||||
|
||||
/**
|
||||
* Displays the value for core's only setting
|
||||
*
|
||||
* @param {object} config - The option config
|
||||
* @param {number} current - The current (count) value
|
||||
* @param {bool} changed - Whether or not the value is non-default
|
||||
*/
|
||||
export const MenuOnlySettingValue = ({ current, config }) => (
|
||||
<MenuHighlightValue
|
||||
current={current?.length}
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
export const UiPreferencesMenu = ({ Swizzled, update, state, Design }) => {
|
||||
const structure = Swizzled.methods.menuUiPreferencesStructure()
|
||||
|
||||
const drillProps = { Design, state, update }
|
||||
const inputs = {
|
||||
ux: (props) => <Swizzled.components.MenuUxSettingInput {...drillProps} {...props} />,
|
||||
aside: (props) => <Swizzled.components.MenuListInput {...drillProps} {...props} />,
|
||||
kiosk: (props) => <Swizzled.components.MenuListInput {...drillProps} {...props} />,
|
||||
rotate: (props) => <Swizzled.components.MenuListInput {...drillProps} {...props} />,
|
||||
renderer: (props) => <Swizzled.components.MenuListInput {...drillProps} {...props} />,
|
||||
}
|
||||
const values = {
|
||||
ux: (props) => <Swizzled.components.Ux ux={state.ui.ux} {...props} />,
|
||||
aside: Swizzled.components.MenuListValue,
|
||||
kiosk: Swizzled.components.MenuListValue,
|
||||
rotate: Swizzled.components.MenuListValue,
|
||||
renderer: Swizzled.components.MenuListValue,
|
||||
}
|
||||
|
||||
return (
|
||||
<Swizzled.components.MenuItemGroup
|
||||
{...{
|
||||
structure,
|
||||
ux: state.ui?.ux,
|
||||
currentValues: state.ui || {},
|
||||
Item: (props) => (
|
||||
<Swizzled.components.UiPreference
|
||||
updateHandler={update}
|
||||
{...{ inputs, values, Swizzled, Design }}
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
isFirst: true,
|
||||
name: 'pe:uiPreferences',
|
||||
language: state.locale,
|
||||
passProps: {
|
||||
ux: state.ui?.ux,
|
||||
settings: state.settings,
|
||||
patternConfig: Design.patternConfig,
|
||||
},
|
||||
updateHandler: update.ui,
|
||||
isDesignOptionsGroup: false,
|
||||
Swizzled,
|
||||
state,
|
||||
Design,
|
||||
inputs,
|
||||
values,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export const UiPreference = ({ Swizzled, name, ux, ...rest }) => (
|
||||
<Swizzled.components.MenuItem
|
||||
{...rest}
|
||||
name={name}
|
||||
allowToggle={!['ux', 'view'].includes(name) && ux > 3}
|
||||
ux={ux}
|
||||
/>
|
||||
)
|
|
@ -100,7 +100,7 @@ export const viewLabels = {
|
|||
t: 'Choose a different view',
|
||||
d: 'fixme',
|
||||
},
|
||||
undos: {
|
||||
undo: {
|
||||
t: 'Undo History',
|
||||
d: 'Time-travel through your recent pattern changes',
|
||||
},
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// Dependencies
|
||||
import { defaultConfig } from '../config/index.mjs'
|
||||
// Components
|
||||
import {
|
||||
ErrorIcon,
|
||||
|
@ -35,9 +37,10 @@ export function draft(Design, settings) {
|
|||
|
||||
return data
|
||||
}
|
||||
export function flattenFlags(flags, config) {
|
||||
|
||||
export function flattenFlags(flags) {
|
||||
const all = {}
|
||||
for (const type of config.flagTypes) {
|
||||
for (const type of defaultConfig.flagTypes) {
|
||||
let i = 0
|
||||
if (flags[type]) {
|
||||
for (const flag of Object.values(flags[type])) {
|
||||
|
|
|
@ -1,13 +1,22 @@
|
|||
export function menuUiPreferencesStructure(Swizzled) {
|
||||
const uiUx = Swizzled.config.uxLevels.ui
|
||||
import { defaultConfig } from '../config/index.mjs'
|
||||
import {
|
||||
MenuIcon,
|
||||
KioskIcon,
|
||||
RotateIcon,
|
||||
RocketIcon,
|
||||
UxIcon,
|
||||
} from '@freesewing/react/components/Icon'
|
||||
|
||||
export function menuUiPreferencesStructure() {
|
||||
const uiUx = defaultConfig.uxLevels.ui
|
||||
const uiPreferences = {
|
||||
ux: {
|
||||
ux: uiUx.ux,
|
||||
emoji: '🖥️',
|
||||
list: [1, 2, 3, 4, 5],
|
||||
choiceTitles: {},
|
||||
icon: Swizzled.components.UxIcon,
|
||||
dflt: Swizzled.config.defaultUx,
|
||||
icon: UxIcon,
|
||||
dflt: defaultConfig.defaultUx,
|
||||
},
|
||||
aside: {
|
||||
ux: uiUx.aside,
|
||||
|
@ -17,7 +26,7 @@ export function menuUiPreferencesStructure(Swizzled) {
|
|||
1: 'pe:withAside',
|
||||
},
|
||||
dflt: 1,
|
||||
icon: Swizzled.components.MenuIcon,
|
||||
icon: MenuIcon,
|
||||
},
|
||||
kiosk: {
|
||||
ux: uiUx.kiosk,
|
||||
|
@ -27,7 +36,7 @@ export function menuUiPreferencesStructure(Swizzled) {
|
|||
1: 'pe:kioskMode',
|
||||
},
|
||||
dflt: 0,
|
||||
icon: Swizzled.components.KioskIcon,
|
||||
icon: KioskIcon,
|
||||
},
|
||||
rotate: {
|
||||
ux: uiUx.rotate,
|
||||
|
@ -37,7 +46,7 @@ export function menuUiPreferencesStructure(Swizzled) {
|
|||
1: 'pe:rotateYes',
|
||||
},
|
||||
dflt: 0,
|
||||
icon: Swizzled.components.RotateIcon,
|
||||
icon: RotateIcon,
|
||||
},
|
||||
renderer: {
|
||||
ux: uiUx.renderer,
|
||||
|
@ -51,7 +60,7 @@ export function menuUiPreferencesStructure(Swizzled) {
|
|||
svg: 'SVG',
|
||||
},
|
||||
dflt: 'react',
|
||||
icon: Swizzled.components.RocketIcon,
|
||||
icon: RocketIcon,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
import mustache from 'mustache'
|
||||
|
||||
export const FlagTypeIcon = ({ Swizzled, type, className = 'w-6 h-6' }) => {
|
||||
const Icon = Swizzled.components[`Flag${Swizzled.methods.capitalize(type)}Icon`]
|
||||
|
||||
return Icon ? <Icon className={className} /> : null
|
||||
}
|
||||
|
||||
export const Flag = ({ Swizzled, data, handleUpdate }) => {
|
||||
const btnIcon = data.suggest?.icon ? (
|
||||
<Swizzled.components.FlagTypeIcon type={data.suggest.icon} className="w-5 h-6 sm:w-6 h-6" />
|
||||
) : null
|
||||
const { t } = Swizzled.methods
|
||||
|
||||
const button =
|
||||
data.suggest?.text && data.suggest?.update ? (
|
||||
<button
|
||||
className={`btn btn-secondary btn-outline flex flex-row items-center ${
|
||||
btnIcon ? 'gap-6' : ''
|
||||
}`}
|
||||
onClick={() => handleUpdate(data.suggest.update)}
|
||||
>
|
||||
{btnIcon}
|
||||
{t(data.suggest.text)}
|
||||
</button>
|
||||
) : null
|
||||
|
||||
const desc = data.replace ? mustache.render(t(data.desc), data.replace) : t(data.desc)
|
||||
const notes = data.notes
|
||||
? Array.isArray(data.notes)
|
||||
? '\n\n' +
|
||||
data.notes
|
||||
.map((note) => (data.replace ? mustache.render(t(note), data.replace) : t(note)))
|
||||
.join('\n\n')
|
||||
: '\n\n' + (data.replace ? mustache.render(t(data.notes), data.replace) : t(data.notes))
|
||||
: null
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-2 items-start">
|
||||
<div className="first:mt-0 grow md flag">
|
||||
<pre>{desc}</pre>
|
||||
<pre>{notes}</pre>
|
||||
</div>
|
||||
{button ? <div className="mt-2 w-full flex flex-row justify-end">{button}</div> : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
//<Mdx md={notes ? desc + notes : desc} />
|
||||
|
||||
export const FlagsAccordionTitle = ({ flags, Swizzled }) => {
|
||||
const { t } = Swizzled.methods
|
||||
const flagList = Swizzled.methods.flattenFlags(flags)
|
||||
|
||||
if (Object.keys(flagList).length < 1) return null
|
||||
|
||||
return (
|
||||
<>
|
||||
<h5 className="flex flex-row gap-2 items-center justify-between w-full">
|
||||
<span className="text-left">
|
||||
{t('pe:flagMenu.t')} ({Object.keys(flagList).length})
|
||||
</span>
|
||||
<Swizzled.components.FlagTypeIcon className="w-8 h-8" />
|
||||
</h5>
|
||||
<p className="text-left">
|
||||
{Object.keys(flagList).length > 1 ? t('pe:flagMenuMany.d') : t('pe:flagMenuOne.d')}
|
||||
</p>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export const FlagsAccordionEntries = ({ flags, update, Swizzled }) => {
|
||||
const flagList = Swizzled.methods.flattenFlags(flags)
|
||||
const { t } = Swizzled.methods
|
||||
|
||||
if (Object.keys(flagList).length < 1) return null
|
||||
|
||||
const handleUpdate = (config) => {
|
||||
if (config.settings) update.settings(...config.settings)
|
||||
if (config.ui) update.ui(...config.settings)
|
||||
}
|
||||
|
||||
return (
|
||||
<Swizzled.components.SubAccordion
|
||||
items={Object.entries(flagList).map(([key, flag], i) => {
|
||||
const title = flag.replace ? mustache.render(t(flag.title), flag.replace) : t(flag.title)
|
||||
|
||||
return [
|
||||
<div className="w-full flex flex-row gap2 justify-between" key={i}>
|
||||
<div className="flex flex-row items-center gap-2">
|
||||
<div className="no-shrink">
|
||||
<Swizzled.components.FlagIcon type={flag.type} />
|
||||
</div>
|
||||
<span className="font-medium text-left">{title}</span>
|
||||
</div>
|
||||
<span className="uppercase font-bold">{flag.type}</span>
|
||||
</div>,
|
||||
<Swizzled.components.Flag key={key} t={t} data={flag} handleUpdate={handleUpdate} />,
|
||||
key,
|
||||
]
|
||||
})}
|
||||
/>
|
||||
)
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
export const Ux = ({ Swizzled, ux = 0 }) => (
|
||||
<div className="flex flex-row">
|
||||
{[0, 1, 2, 3, 4].map((i) => (
|
||||
<Swizzled.components.CircleIcon
|
||||
key={i}
|
||||
fill={i < ux ? true : false}
|
||||
className={`w-6 h-6 ${i < ux ? 'stroke-secondary fill-secondary' : 'stroke-current'}`}
|
||||
fillOpacity={0.3}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
|
@ -242,6 +242,13 @@ export const FingerprintIcon = (props) => (
|
|||
</IconWrapper>
|
||||
)
|
||||
|
||||
// Looks lik an exclamation point inside a circle
|
||||
export const FixmeIcon = (props) => (
|
||||
<IconWrapper {...props}>
|
||||
<path d="M12 9v3.75m9-.75a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 3.75h.008v.008H12v-.008Z" />
|
||||
</IconWrapper>
|
||||
)
|
||||
|
||||
// Looks lik a flag
|
||||
export const FlagIcon = (props) => (
|
||||
<IconWrapper {...props}>
|
||||
|
@ -753,12 +760,3 @@ export const ViewDocsIcon = DocsIcon
|
|||
export const ViewDesignsIcon = DesignIcon
|
||||
export const ViewViewPickerIcon = UiIcon
|
||||
export const ViewUndosIcon = BackIcon
|
||||
// Flag icons
|
||||
export const FlagNoteIcon = ChatIcon
|
||||
export const FlagInfoIcon = DocsIcon
|
||||
export const FlagTipIcon = TipIcon
|
||||
export const FlagWarningIcon = WarningIcon
|
||||
export const FlagErrorIcon = ErrorIcon
|
||||
export const FlagFixmeIcon = WrenchIcon
|
||||
export const FlagExpandIcon = ExpandIcon
|
||||
export const FlagOtionsIcon = OptionsIcon
|
||||
|
|
15
packages/react/components/Ux/index.mjs
Normal file
15
packages/react/components/Ux/index.mjs
Normal file
|
@ -0,0 +1,15 @@
|
|||
import React from 'react'
|
||||
import { CircleIcon } from '@freesewing/react/components/Icon'
|
||||
|
||||
export const Ux = ({ ux = 0 }) => (
|
||||
<div className="flex flex-row">
|
||||
{[0, 1, 2, 3, 4].map((i) => (
|
||||
<CircleIcon
|
||||
key={i}
|
||||
fill={i < ux ? true : false}
|
||||
className={`tw-w-6 tw-h-6 ${i < ux ? 'tw-stroke-secondary tw-fill-secondary' : 'tw-stroke-current'}`}
|
||||
fillOpacity={0.3}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
|
@ -58,6 +58,7 @@
|
|||
"./components/Table": "./components/Table/index.mjs",
|
||||
"./components/Time": "./components/Time/index.mjs",
|
||||
"./components/Uuid": "./components/Uuid/index.mjs",
|
||||
"./components/Ux": "./components/Ux/index.mjs",
|
||||
"./components/Yaml": "./components/Yaml/index.mjs",
|
||||
"./components/Xray": "./components/Xray/index.mjs",
|
||||
"./context/LoadingStatus": "./context/LoadingStatus/index.mjs",
|
||||
|
@ -81,12 +82,13 @@
|
|||
"highlight.js": "^11.11.0",
|
||||
"html-react-parser": "^5.0.7",
|
||||
"luxon": "^3.5.0",
|
||||
"nuqs": "^2.3.0",
|
||||
"nuqs": "^1.17.6",
|
||||
"react-markdown": "^9.0.1",
|
||||
"tlds": "^1.255.0",
|
||||
"use-local-storage-state": "19.1.0",
|
||||
"use-session-storage-state": "^19.0.0"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"files": [
|
||||
"components/**",
|
||||
"hooks/**",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue