1
0
Fork 0

feat: Upgrade to TailwindCSS 4 & DaisyUI 5 (#263)

Also fixes #251

Reviewed-on: https://codeberg.org/freesewing/freesewing/pulls/263
Co-authored-by: joostdecock <joost@joost.at>
Co-committed-by: joostdecock <joost@joost.at>
This commit is contained in:
joostdecock 2025-04-18 08:07:13 +00:00 committed by Joost De Cock
parent a2863e5158
commit 44e04a4cef
164 changed files with 2361 additions and 2658 deletions

View file

@ -5,19 +5,15 @@ import React, { useState } from 'react'
* So instead, we handle this in React state
*/
const getProps = (isActive = false) => ({
className: `tw-p-2 tw-px-4 tw-rounded-lg tw-bg-transparent tw-shadow hover:tw-cursor-pointer
tw-w-full tw-h-auto tw-content-start tw-text-left tw-bg-opacity-20
${isActive ? 'hover:tw-bg-transparent' : 'hover:tw-bg-secondary hover:tw-bg-opacity-10'}`,
className: `tw:p-2 tw:px-4 tw:rounded-lg tw:bg-transparent tw:shadow tw:hover:cursor-pointer
tw:w-full tw:h-auto tw:content-start tw:text-left
${isActive ? 'tw:hover:bg-transparent' : 'tw:hover:bg-secondary/10'}`,
})
const getSubProps = (isActive) => ({
className: `tw-p-2 tw-px-4 tw-rounded-none tw-bg-transparent tw-w-full tw-h-auto
tw-content-start tw-bg-secondary tw-text-left tw-bg-opacity-20
${
isActive
? 'tw-bg-opacity-100 hover:tw-bg-transparent tw-shadow'
: 'hover:tw-bg-opacity-10 hover:tw-bg-secondary '
}`,
className: `tw:p-2 tw:px-4 tw:rounded-none tw:bg-transparent tw:w-full tw:h-auto
tw:content-start tw:bg-secondary/20 tw:text-left
${isActive ? 'tw:bg-secondary tw:hover:bg-transparent tw:shadow' : 'tw:hover:bg-secondary/10 '}`,
})
const components = {
@ -43,7 +39,7 @@ export const BaseAccordion = ({
<div key={i} {...propsGetter(true)}>
<Component
onClick={setActive}
className="tw-w-full tw-bg-transparent tw-border-0 hover:tw-bg-secondary hover:tw-bg-opacity-20 hover:tw-cursor-pointer"
className="tw:w-full tw:bg-transparent tw:border-0 tw:hover:bg-secondary/20 tw:hover:cursor-pointer"
>
{item[0]}
</Component>

View file

@ -11,7 +11,7 @@ export const AsideViewMenuButton = ({
}) => {
const className = `w-full flex flex-row items-center px-4 py-2 ${extraClasses} ${
active
? 'font-bold lg:font-normal bg-secondary bg-opacity-10 lg:bg-secondary lg:text-secondary-content lg:bg-opacity-50'
? 'font-bold lg:font-normal bg-secondary/10 lg:bg-secondary/50 lg:text-secondary-content'
: 'lg:bg-neutral lg:text-neutral-content'
}`
const span = <span className="block grow text-left">{label}</span>

View file

@ -31,7 +31,7 @@ const flagIcons = {
warning: WarningIcon,
}
export const FlagTypeIcon = ({ type, className = 'tw-w-6 tw-h-6' }) => {
export const FlagTypeIcon = ({ type, className = 'tw:w-6 tw:h-6' }) => {
const Icon = flagIcons[type] || FixmeIcon
return <Icon className={className} />
@ -39,14 +39,14 @@ export const FlagTypeIcon = ({ type, className = 'tw-w-6 tw-h-6' }) => {
export const Flag = ({ data, handleUpdate, strings }) => {
const btnIcon = data.suggest?.icon ? (
<FlagTypeIcon type={data.suggest.icon} className="tw-w-5 tw-h-6 sm:tw-w-6 tw-h-6" />
<FlagTypeIcon type={data.suggest.icon} className="tw:w-5 tw:h-6 tw:sm:w-6 tw:h-6" />
) : null
const button =
data.suggest?.text && data.suggest?.update ? (
<button
className={`tw-daisy-btn tw-daisy-btn-secondary tw-daisy-btn-outline tw-flex tw-flex-row tw-items-center ${
btnIcon ? 'tw-gap-6' : ''
className={`tw:daisy-btn tw:daisy-btn-secondary tw:daisy-btn-outline tw:flex tw:flex-row tw:items-center ${
btnIcon ? 'tw:gap-6' : ''
}`}
onClick={() => handleUpdate(data.suggest.update)}
>
@ -75,8 +75,8 @@ export const Flag = ({ data, handleUpdate, strings }) => {
: 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 tw-flex tw-flex-col tw-gap-2">
<div className="tw:flex tw:flex-col tw:gap-2 tw:items-start">
<div className="tw:first:mt-0 tw:grow md flag tw:flex tw:flex-col tw:gap-2">
{desc ? (
<MiniTip>
<Markdown>{strings[desc] || desc}</Markdown>
@ -89,7 +89,7 @@ export const Flag = ({ data, handleUpdate, strings }) => {
) : null}
</div>
{button ? (
<div className="tw-mt-2 tw-w-full tw-flex tw-flex-row tw-justify-end">{button}</div>
<div className="tw:mt-2 tw:w-full tw:flex tw:flex-row tw:justify-end">{button}</div>
) : null}
</div>
)
@ -102,11 +102,11 @@ export const FlagsAccordionTitle = ({ flags }) => {
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 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">
<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.'}
@ -131,14 +131,14 @@ export const FlagsAccordionEntries = ({ flags, update, pattern, strings }) => {
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">
<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">{strings[title] || title}</span>
<span className="tw:font-medium tw:text-left">{strings[title] || title}</span>
</div>
<span className="tw-uppercase tw-font-bold">{flag.type}</span>
<span className="tw:uppercase tw:font-bold">{flag.type}</span>
</div>,
<Flag key={key} data={flag} strings={strings} handleUpdate={handleUpdate} />,
key,

View file

@ -61,7 +61,7 @@ export const HeaderMenuIcon = (props) => {
// FIXME: Remove this when ready
if (!headerMenuIcons[name]) console.log('FIXME: Add headerMenuIcon for ', name)
return <Icon {...props} className={`tw-h-5 tw-w-5 ${extraClasses}`} />
return <Icon {...props} className={`tw:h-5 tw:w-5 ${extraClasses}`} />
}
export const HeaderMenuDraftView = (props) => {
@ -70,7 +70,7 @@ export const HeaderMenuDraftView = (props) => {
return (
<>
<div className="tw-flex tw-flex-row tw-gap-0.5 lg:tw-gap-1">
<div className="tw:flex tw:flex-row tw:gap-0.5 tw:lg:gap-1">
<HeaderMenuDraftViewDesignOptions {...props} i18n={i18n} />
<HeaderMenuDraftViewCoreSettings {...props} i18n={i18n} />
<HeaderMenuDraftViewUiPreferences {...props} i18n={i18n} />
@ -103,8 +103,8 @@ export const HeaderMenuTestViewDesignOptions = (props) => {
tooltip="See how design options influence the pattern being generated."
toggle={
<>
<HeaderMenuIcon name="options" extraClasses="tw-text-secondary" />
<span className="tw-hidden lg:tw-inline">Test Options</span>
<HeaderMenuIcon name="options" extraClasses="tw:text-secondary" />
<span className="tw:hidden tw:lg:inline">Test Options</span>
</>
}
>
@ -121,8 +121,8 @@ export const HeaderMenuTestViewDesignMeasurements = (props) => {
tooltip="See how changes to a measurment influence the pattern being generated."
toggle={
<>
<HeaderMenuIcon name="options" extraClasses="tw-text-secondary" />
<span className="tw-hidden lg:tw-inline">Test Measurements</span>
<HeaderMenuIcon name="options" extraClasses="tw:text-secondary" />
<span className="tw:hidden tw:lg:inline">Test Measurements</span>
</>
}
>
@ -145,7 +145,7 @@ export const HeaderMenuDropdown = (props) => {
disabled
tabIndex={0}
role="button"
className={`tw-daisy-btn tw-daisy-btn-ghost hover:tw-bg-secondary hover:tw-bg-opacity-20 hover:tw-border-solid hover:tw-border-2 hover:tw-border-secondary tw-border tw-border-secondary tw-border-2 tw-border-dotted tw-daisy-btn-sm tw-px-2 tw-z-20 tw-relative`}
className={`tw:daisy-btn tw:daisy-btn-ghost tw:hover:bg-secondary/20 tw:hover:border-solid tw:hover:border-2 tw:hover:border-secondary tw:border tw:border-secondary tw:border-2 tw:border-dotted tw:daisy-btn-sm tw:px-2 tw:z-20 tw:relative`}
>
{toggle}
</button>
@ -153,26 +153,26 @@ export const HeaderMenuDropdown = (props) => {
) : (
<Tooltip tip={tooltip}>
<div
className={`tw-daisy-dropdown ${open === id ? 'tw-daisy-dropdown-open tw-z-20' : ''} ${end ? ' tw-daisy-dropdown-end' : ''}`}
className={`tw:daisy-dropdown ${open === id ? 'tw:daisy-dropdown-open tw:z-20' : ''} ${end ? ' tw:daisy-dropdown-end' : ''}`}
>
<div
tabIndex={0}
role="button"
className="tw-daisy-btn tw-daisy-btn-ghost hover:tw-bg-secondary hover:tw-bg-opacity-20 tw-border-secondary/10 hover:tw-border-2 hover:tw-border-secondary tw-border tw-border-secondary tw-border-2 tw-border-solid tw-daisy-btn-sm tw-px-2 tw-z-20 tw-relative"
className="tw:daisy-btn tw:daisy-btn-ghost tw:hover:bg-secondary/20 tw:border-secondary/10 tw:hover:border-2 tw:hover:border-secondary tw:border tw:border-secondary tw:border-2 tw:border-solid tw:daisy-btn-sm tw:px-2 tw:z-20 tw:relative"
onClick={() => setOpen(open === id ? false : id)}
>
{toggle}
</div>
<div
tabIndex={0}
className="tw-daisy-dropdown-content tw-bg-base-100 tw-bg-opacity-90 tw-z-20 tw-shadow tw-left-0 !tw-fixed md:!tw-absolute tw-top-12 tw-w-screen md:tw-max-w-md tw-overflow-y-scroll tw-mb-12 tw-h-fit"
className="tw:daisy-dropdown-content tw:bg-base-100/90 tw:z-20 tw:shadow tw:left-0 tw:fixed! tw:md:absolute! tw:top-12 tw:w-screen tw:md:max-w-md tw:overflow-y-scroll tw:mb-12 tw:h-fit"
style={{ maxHeight: 'calc(100vh - 12rem)' }}
>
{props.children}
</div>
{open === id && (
<div
className="tw-w-screen tw-h-screen tw-absolute tw-top-10 tw-left-0 tw-opacity-0"
className="tw:w-screen tw:h-screen tw:absolute tw:top-10 tw:left-0 tw:opacity-0"
style={{ width: '200vw', transform: 'translateX(-100vw)' }}
onClick={() => setOpen(false)}
></div>
@ -189,8 +189,8 @@ export const HeaderMenuDraftViewDesignOptions = (props) => (
tooltip="These options are specific to this design. You can use them to customize your pattern in a variety of ways."
toggle={
<>
<HeaderMenuIcon name="options" extraClasses="tw-text-secondary" />
<span className="tw-hidden lg:tw-inline tw-capitalize">
<HeaderMenuIcon name="options" extraClasses="tw:text-secondary" />
<span className="tw:hidden tw:lg:inline tw:capitalize">
{props.state.design ? props.state.design : 'Design'} Options
</span>
</>
@ -208,8 +208,8 @@ export const HeaderMenuDraftViewCoreSettings = (props) => {
id="coreSettings"
toggle={
<>
<HeaderMenuIcon name="settings" extraClasses="tw-text-secondary" />
<span className="tw-hidden lg:tw-inline">Core Settings</span>
<HeaderMenuIcon name="settings" extraClasses="tw:text-secondary" />
<span className="tw:hidden tw:lg:inline">Core Settings</span>
</>
}
>
@ -226,8 +226,8 @@ export const HeaderMenuDraftViewUiPreferences = (props) => {
id="uiPreferences"
toggle={
<>
<HeaderMenuIcon name="ui" extraClasses="tw-text-secondary" />
<span className="tw-hidden lg:tw-inline">UI Preferences</span>
<HeaderMenuIcon name="ui" extraClasses="tw:text-secondary" />
<span className="tw:hidden tw:lg:inline">UI Preferences</span>
</>
}
>
@ -246,8 +246,8 @@ export const HeaderMenuDraftViewFlags = (props) => {
id="flags"
toggle={
<>
<HeaderMenuIcon name="flag" extraClasses="tw-text-secondary" />
<span className="tw-hidden lg:tw-inline">
<HeaderMenuIcon name="flag" extraClasses="tw:text-secondary" />
<span className="tw:hidden tw:lg:inline">
Flags
<span>({count})</span>
</span>
@ -262,8 +262,8 @@ export const HeaderMenuDraftViewFlags = (props) => {
export const HeaderMenuDraftViewIcons = (props) => {
const { update, state } = props
const Button = HeaderMenuButton
const size = 'tw-w-5 tw-h-5'
const muted = 'tw-text-current tw-opacity-50'
const size = 'tw:w-5 tw:h-5'
const muted = 'tw:text-current tw:opacity-50'
const ux = state.ui.ux
const levels = {
...props.config.uxLevels.core,
@ -271,14 +271,14 @@ export const HeaderMenuDraftViewIcons = (props) => {
}
return (
<div className="tw-hidden lg:tw-flex tw-flex-row tw-flex-wrap tw-items-center tw-justify-center tw-px-0.5 lg:tw-px-1">
<div className="tw:hidden tw:lg:flex tw:flex-row tw:flex-wrap tw:items-center tw:justify-center tw:px-0.5 tw:lg:px-1">
{ux >= levels.sa ? (
<Button
lgOnly
updateHandler={update.toggleSa}
tooltip="Turns Seam Allowance on or off (see Core Settings)"
>
<SaIcon className={`${size} ${state.settings.sabool ? 'tw-text-secondary' : muted}`} />
<SaIcon className={`${size} ${state.settings.sabool ? 'tw:text-secondary' : muted}`} />
</Button>
) : null}
{ux >= levels.units ? (
@ -291,7 +291,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
>
<UnitsIcon
className={`${size} ${
state.settings.units === 'imperial' ? 'tw-text-secondary' : muted
state.settings.units === 'imperial' ? 'tw:text-secondary' : muted
}`}
/>
</Button>
@ -303,7 +303,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
tooltip="Turns Paperless on or off (see Core Settings)"
>
<PaperlessIcon
className={`${size} ${state.settings.paperless ? 'tw-text-secondary' : muted}`}
className={`${size} ${state.settings.paperless ? 'tw:text-secondary' : muted}`}
/>
</Button>
) : null}
@ -314,7 +314,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
tooltip="Turns Details on or off (see Core Settings)"
>
<DetailIcon
className={`${size} ${!state.settings.complete ? 'tw-text-secondary' : muted}`}
className={`${size} ${!state.settings.complete ? 'tw:text-secondary' : muted}`}
/>
</Button>
) : null}
@ -325,7 +325,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
tooltip="Turns Expand on or off (see Core Settings)"
>
<ExpandIcon
className={`${size} ${state.settings.expand ? 'tw-text-secondary' : muted}`}
className={`${size} ${state.settings.expand ? 'tw:text-secondary' : muted}`}
/>
</Button>
) : null}
@ -336,7 +336,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
updateHandler={() => update.ui('aside', state.ui.aside ? 0 : 1)}
tooltip="Toggles the side menu (see UI Preferences)"
>
<AsideIcon className={`${size} ${state.ui.aside ? 'tw-text-secondary' : muted}`} />
<AsideIcon className={`${size} ${state.ui.aside ? 'tw:text-secondary' : muted}`} />
</Button>
) : null}
{ux >= levels.renderer ? (
@ -348,7 +348,7 @@ export const HeaderMenuDraftViewIcons = (props) => {
tooltip="Switches the Render Engine between React and SVG (see UI Preferences)"
>
<RocketIcon
className={`${size} ${state.ui.renderer === 'svg' ? 'tw-text-secondary' : muted}`}
className={`${size} ${state.ui.renderer === 'svg' ? 'tw:text-secondary' : muted}`}
/>
</Button>
) : null}
@ -359,18 +359,18 @@ export const HeaderMenuDraftViewIcons = (props) => {
export const HeaderMenuUndoIcons = (props) => {
const { update, state, Design } = props
const Button = HeaderMenuButton
const size = 'tw-w-5 tw-h-5'
const size = 'tw:w-5 tw:h-5'
const undos = state._?.undos && state._.undos.length > 0 ? state._.undos : false
return (
<div className="tw-flex tw-flex-row tw-flex-wrap tw-items-center tw-justify-center tw-px-0.5 lg:tw-px-1">
<div className="tw:flex tw:flex-row tw:flex-wrap tw:items-center tw:justify-center tw:px-0.5 tw:lg:px-1">
<Button
lgOnly
updateHandler={() => update.restore(0, state._)}
tooltip="Undo the most recent change"
disabled={undos ? false : true}
>
<UndoIcon className={`${size} ${undos ? 'tw-text-secondary' : ''}`} text="1" />
<UndoIcon className={`${size} ${undos ? 'tw:text-secondary' : ''}`} text="1" />
</Button>
<Button
lgOnly
@ -378,7 +378,7 @@ export const HeaderMenuUndoIcons = (props) => {
tooltip="Undo all changes since the last save point"
disabled={undos ? false : true}
>
<UndoIcon className={`${size} ${undos ? 'tw-text-secondary' : ''}`} text="A" />
<UndoIcon className={`${size} ${undos ? 'tw:text-secondary' : ''}`} text="A" />
</Button>
<HeaderMenuDropdown
end
@ -388,13 +388,13 @@ export const HeaderMenuUndoIcons = (props) => {
disabled={undos ? false : true}
toggle={
<>
<UndoIcon className="tw-w-4 tw-h-4" stroke={3} />
<span className="tw-hidden lg:tw-inline">Undo</span>
<UndoIcon className="tw:w-4 tw:h-4" stroke={3} />
<span className="tw:hidden tw:lg:inline">Undo</span>
</>
}
>
{undos ? (
<ul className="tw-daisy-dropdown-content tw-bg-base-100 tw-bg-opacity-90 tw-z-20 tw-shadow tw-left-0 !tw-fixed md:!tw-absolute tw-w-screen md:tw-w-96 tw-px-4 md:tw-p-2 md:tw-pt-0 tw-contents">
<ul className="tw:daisy-dropdown-content tw:bg-base-100/90 tw:z-20 tw:shadow tw:left-0 tw:fixed! tw:md:absolute! tw:w-screen tw:md:w-96 tw:px-4 tw:md:p-2 tw:md:pt-0 tw:contents">
{undos.slice(0, 9).map((step, index) => (
<li key={index}>
<UndoStep {...{ step, update, state, Design, index }} compact />
@ -402,9 +402,9 @@ export const HeaderMenuUndoIcons = (props) => {
))}
<li key="view">
<ButtonFrame dense onClick={() => update.view('undos')}>
<div className="tw-flex tw-flex-row tw-items-center tw-align-center tw-justify-between tw-gap-2 tw-w-full">
<div className="tw-flex tw-flex-row tw-items-center tw-align-start tw-gap-2 tw-grow">
<UndoIcon className="tw-w-5 tw-h-5 tw-text-secondary" />
<div className="tw:flex tw:flex-row tw:items-center tw:align-center tw:justify-between tw:gap-2 tw:w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:align-start tw:gap-2 tw:grow">
<UndoIcon className="tw:w-5 tw:h-5 tw:text-secondary" />
{viewLabels.undos.t}
</div>
{undos.length}
@ -418,10 +418,10 @@ export const HeaderMenuUndoIcons = (props) => {
updateHandler={update.clearPattern}
tooltip="Reset all settings, but keep the design and measurements"
>
<TrashIcon className={`${size} tw-text-secondary`} />
<TrashIcon className={`${size} tw:text-secondary`} />
</Button>
<Button updateHandler={update.clearAll} tooltip="Reset the editor completely">
<ResetAllIcon className={`${size} tw-text-secondary`} />
<ResetAllIcon className={`${size} tw:text-secondary`} />
</Button>
</div>
)
@ -430,11 +430,11 @@ export const HeaderMenuUndoIcons = (props) => {
export const HeaderMenuTestIcons = (props) => {
const { update, state, Design } = props
const Button = HeaderMenuButton
const size = 'tw-w-5 tw-h-5'
const size = 'tw:w-5 tw:h-5'
const undos = state._?.undos && state._.undos.length > 0 ? state._.undos : false
return (
<div className="tw-flex tw-flex-row tw-flex-wrap tw-items-center tw-justify-center tw-px-0.5 lg:tw-px-1">
<div className="tw:flex tw:flex-row tw:flex-wrap tw:items-center tw:justify-center tw:px-0.5 tw:lg:px-1">
<Button
updateHandler={() => update.settings('sample', undefined)}
tooltip="Clear the test so you can select another"
@ -449,7 +449,7 @@ export const HeaderMenuSaveIcons = (props) => {
const { update, state } = props
const backend = useBackend()
const Button = HeaderMenuButton
const size = 'tw-w-5 tw-h-5'
const size = 'tw:w-5 tw:h-5'
const saveable = state._?.undos && state._.undos.length > 0
/*
@ -473,22 +473,22 @@ export const HeaderMenuSaveIcons = (props) => {
}
return (
<div className="tw-flex tw-flex-row tw-flex-wrap tw-items-center tw-justify-center tw-px-2">
<div className="tw:flex tw:flex-row tw:flex-wrap tw:items-center tw:justify-center tw:px-2">
<Button updateHandler={savePattern} tooltip="Save pattern" disabled={saveable ? false : true}>
<SaveIcon className={`${size} ${saveable ? 'tw-text-success' : ''}`} />
<SaveIcon className={`${size} ${saveable ? 'tw:text-success' : ''}`} />
</Button>
<Button updateHandler={() => update.view('save')} tooltip="Save pattern as...">
<SaveAsIcon className={`${size} tw-text-secondary`} />
<SaveAsIcon className={`${size} tw:text-secondary`} />
</Button>
<Button updateHandler={() => update.view('export')} tooltip="Export pattern">
<ExportIcon className={`${size} tw-text-secondary`} />
<ExportIcon className={`${size} tw:text-secondary`} />
</Button>
</div>
)
}
export const HeaderMenuIconSpacer = () => (
<span className="tw-hidden lg:tw-inline tw-px-1 tw-font-bold tw-opacity-30">|</span>
<span className="tw:hidden tw:lg:inline tw:px-1 tw:font-bold tw:opacity-30">|</span>
)
export const HeaderMenuButton = ({
@ -500,7 +500,7 @@ export const HeaderMenuButton = ({
}) => (
<Tooltip tip={tooltip}>
<button
className={`${lgOnly ? 'tw-hidden lg:tw-inline' : ''} tw-daisy-btn tw-daisy-btn-ghost tw-daisy-btn-sm tw-px-1 disabled:tw-bg-transparent`}
className={`${lgOnly ? 'tw:hidden tw:lg:inline' : ''} tw:daisy-btn tw:daisy-btn-ghost tw:daisy-btn-sm tw:px-1 tw:disabled:bg-transparent`}
onClick={updateHandler}
disabled={disabled}
>
@ -533,19 +533,17 @@ export const HeaderMenuViewMenu = (props) => {
output.push(
<li
key={i}
className="tw-mb-1 tw-flex tw-flex-row tw-items-center tw-justify-between tw-w-full"
className="tw:mb-1 tw:flex tw:flex-row tw:items-center tw:justify-between tw:w-full"
>
<a
className={`tw-w-full tw-text-base-content
tw-flex tw-flex-row tw-items-center tw-gap-2 md:tw-gap-4 tw-p-2 tw-px-4
hover:tw-cursor-pointer hover:tw-text-base-content
hover:tw-bg-secondary hover:tw-bg-opacity-20 ${
viewName === state.view ? 'tw-bg-secondary tw-bg-opacity-20' : ''
}`}
className={`tw:w-full tw:text-base-content
tw:flex tw:flex-row tw:items-center tw:gap-2 tw:md:gap-4 tw:p-2 tw:px-4
tw:hover:cursor-pointer tw:hover:text-base-content
tw:hover:bg-secondary/20 ${viewName === state.view ? 'tw:bg-secondary/20' : ''}`}
onClick={() => update.view(viewName)}
>
<ViewIcon view={viewName} className="tw-w-6 tw-h-6 tw-grow-0" />
<span className="tw-text-left tw-grow tw-font-medium">
<ViewIcon view={viewName} className="tw:w-6 tw:h-6 tw:grow-0" />
<span className="tw:text-left tw:grow tw:font-medium">
{viewLabels[viewName]?.t || viewName}
</span>
</a>
@ -561,8 +559,8 @@ export const HeaderMenuViewMenu = (props) => {
id="views"
toggle={
<>
<HeaderMenuIcon name="right" stroke={3} extraClasses="tw-text-secondary tw-rotate-90" />
<span className="tw-hidden lg:tw-inline">
<HeaderMenuIcon name="right" stroke={3} extraClasses="tw:text-secondary tw:rotate-90" />
<span className="tw:hidden tw:lg:inline">
{viewLabels[state.view] ? viewLabels[state.view].t : 'Views'}
</span>
</>
@ -570,7 +568,7 @@ export const HeaderMenuViewMenu = (props) => {
>
<ul
tabIndex={i}
className="tw-daisy-dropdown-content tw-bg-base-100 tw-bg-opacity-95 tw-z-20 tw-shadow tw-left-0 !tw-fixed md:!tw-absolute tw-w-screen md:tw-max-w-lg md:tw-pt-0 tw-mt-14 md:tw-mt-0 tw-contents"
className="tw:daisy-dropdown-content tw:bg-base-100/95tw:z-20 tw:shadow tw:left-0 tw:fixed! tw:md:absolute! tw:w-screen tw:md:max-w-lg tw:md:pt-0 tw:mt-14 tw:md:mt-0 tw:contents"
>
{output}
</ul>
@ -586,8 +584,8 @@ export const HeaderMenuLayoutView = (props) => (
tooltip="These options are specific to this design. You can use them to customize your pattern in a variety of ways."
toggle={
<>
<HeaderMenuIcon name="layout" extraClasses="tw-text-secondary" />
<span className="tw-hidden lg:tw-inline">Print Settings</span>
<HeaderMenuIcon name="layout" extraClasses="tw:text-secondary" />
<span className="tw:hidden tw:lg:inline">Print Settings</span>
</>
}
>
@ -642,10 +640,10 @@ export const HeaderMenuLayoutViewIcons = (props) => {
return (
<>
<Tooltip tip="Number of pages required for the current layout">
<span className="tw-px-1 tw-font-bold tw-text-sm tw-block tw-h-8 tw-py-1 tw-opacity-80">
<span className="tw:px-1 tw:font-bold tw:text-sm tw:block tw:h-8 tw:py-1 tw:opacity-80">
<span className="">
{count} pages
<span className="tw-pl-1 tw-text-xs tw-font-medium">
<span className="tw:pl-1 tw:text-xs tw:font-medium">
({cols}x{rows}, {blank} blank)
</span>
</span>
@ -653,7 +651,7 @@ export const HeaderMenuLayoutViewIcons = (props) => {
</Tooltip>
<Tooltip tip="Apply this layout to the pattern">
<button
className="tw-daisy-btn tw-daisy-btn-ghost tw-daisy-btn-sm tw-px-1 disabled:tw-bg-transparent tw-text-secondary"
className="tw:daisy-btn tw:daisy-btn-ghost tw:daisy-btn-sm tw:px-1 tw:disabled:bg-transparent tw:text-secondary"
onClick={applyLayout}
disabled={!layoutValid}
>
@ -662,7 +660,7 @@ export const HeaderMenuLayoutViewIcons = (props) => {
</Tooltip>
<Tooltip tip="Generate a PDF that you can print">
<button
className="tw-daisy-btn tw-daisy-btn-ghost tw-daisy-btn-sm tw-px-1 disabled:tw-bg-transparent tw-text-secondary"
className="tw:daisy-btn tw:daisy-btn-ghost tw:daisy-btn-sm tw:px-1 tw:disabled:bg-transparent tw:text-secondary"
onClick={() => update.view('export')}
>
<PrintIcon />
@ -670,7 +668,7 @@ export const HeaderMenuLayoutViewIcons = (props) => {
</Tooltip>
<Tooltip tip="Reset the custom layout">
<button
className="tw-daisy-btn tw-daisy-btn-ghost tw-daisy-btn-sm tw-px-1 disabled:tw-bg-transparent tw-text-secondary"
className="tw:daisy-btn tw:daisy-btn-ghost tw:daisy-btn-sm tw:px-1 tw:disabled:bg-transparent tw:text-secondary"
onClick={resetLayout}
>
<ResetIcon />
@ -705,12 +703,12 @@ export const HeaderMenu = ({ config, Design, pattern, state, update, strings })
return (
<div
className={`tw-flex tw-sticky tw-top-0 ${
state.ui.kiosk ? 'tw-z-50' : 'tw-z-20'
} tw-transition-[top] tw-duration-300 tw-ease-in-out`}
className={`tw:flex tw:sticky tw:top-0 ${
state.ui.kiosk ? 'tw:z-50' : 'tw:z-20'
} tw:transition-[top] tw:duration-300 tw:ease-in-out`}
>
<div
className={`tw-flex tw-flex-row tw-flex-wrap tw-gap-0.5 lg:tw-gap-1 tw-w-full tw-items-start tw-justify-center tw-py-1 md:tw-py-1.5`}
className={`tw:flex tw:flex-row tw:flex-wrap tw:gap-0.5 tw:lg:gap-1 tw:w-full tw:items-start tw:justify-center tw:py-1 tw:md:py-1.5`}
>
<HeaderMenuViewMenu {...{ config, state, update, open, setOpen, strings }} />
<ViewSpecificMenu {...{ config, state, update, Design, pattern, open, setOpen, strings }} />

View file

@ -36,13 +36,13 @@ export const LoadingStatus = ({ state, update }) => {
if (!state._.loading || Object.keys(state._.loading).length < 1) return null
const colorClasses = {
info: 'tw-bg-info tw-text-info-content',
primary: 'tw-bg-primary tw-text-primary-content',
info: 'tw:bg-info tw:text-info-content',
primary: 'tw:bg-primary tw:text-primary-content',
}
return (
<div className="tw-fixed tw-bottom-4 md:tw-buttom-28 tw-left-0 tw-w-full tw-z-30 md:tw-px-4 md:tw-mx-auto mb-4">
<div className="tw-flex tw-flex-col tw-gap-2">
<div className="tw:fixed tw:bottom-4 md:tw:buttom-28 tw:left-0 tw:w-full tw:z-30 tw:md:px-4 tw:md:mx-auto mb-4">
<div className="tw:flex tw:flex-col tw:gap-2">
{Object.entries(state._.loading).map(([id, custom]) => {
const conf = {
...config.defaults,
@ -52,20 +52,20 @@ export const LoadingStatus = ({ state, update }) => {
return (
<div
key={id}
className={`tw-w-full md:tw-max-w-2xl tw-m-auto tw-bg-${
className={`tw:w-full tw:md:max-w-2xl tw:m-auto tw:bg-${
conf.color
} tw-text-${conf.color}-content tw-flex tw-flex-row tw-items-center tw-gap-4 tw-p-4 tw-px-4 ${
conf.fading ? 'tw-opacity-0' : 'tw-opacity-100'
} tw:text-${conf.color}-content tw:flex tw:flex-row tw:items-center tw:gap-4 tw:p-4 tw:px-4 ${
conf.fading ? 'tw:opacity-0' : 'tw:opacity-100'
}
tw-transition-opacity tw-delay-[${config.timeout * 1000 - 400}ms] tw-duration-300
md:tw-rounded-lg tw-shadow tw-text-secondary-content tw-text-lg lg:tw-text-xl tw-font-medium md:tw-bg-opacity-90
${conf.color === 'info' ? 'tw-text-neutral' : ''}
tw:transition-opacity tw:delay-[${config.timeout * 1000 - 400}ms] tw:duration-300
tw:md:rounded-lg tw:shadow tw:text-secondary-content tw:text-lg tw:lg:text-xl tw:font-medium
${conf.color === 'info' ? 'tw:text-neutral' : ''}
`}
>
<span className={`tw-shrink-0 tw-text-${conf.color}-content`}>
<span className={`tw:shrink-0 tw:text-${conf.color}-content`}>
<Icon />
</span>
<div className={conf.color === 'info' ? 'tw-text-neutral tw-w-full' : 'tw-w-full'}>
<div className={conf.color === 'info' ? 'tw:text-neutral tw:w-full' : 'tw:w-full'}>
{conf.msg}
</div>
</div>

View file

@ -21,7 +21,7 @@ export const MeasurementsEditor = ({ Design, update, state, helpProvider = false
}
return (
<div className="tw-max-w-2xl tw-mx-auto">
<div className="tw:max-w-2xl tw:mx-auto">
<h4>Required Measurements</h4>
{Object.keys(Design.patternConfig.measurements).length === 0 ? (
<p>This design does not require any measurements.</p>

View file

@ -407,8 +407,8 @@ const Button = ({ onClickCb, transform, Icon, children, title = '' }) => {
<g transform={transform} className="svg-layout-button group">
<title>{title}</title>
<rect width={rectSize} height={rectSize} className="button" rx="2" ry="2" />
<Icon className="group-hover:tw-text-primary-content" />
<rect width={rectSize} height={rectSize} onClick={_onClick} className="tw-fill-transparent" />
<Icon className="tw:group-hover:text-primary-content" />
<rect width={rectSize} height={rectSize} onClick={_onClick} className="tw:fill-transparent" />
</g>
)
}

View file

@ -30,20 +30,20 @@ export const PatternLayout = (props) => {
return (
<ZoomContextProvider>
<div className="tw-flex tw-flex-col tw-h-full">
<div className="tw:flex tw:flex-col tw:h-full">
<HeaderMenu
state={props.state}
{...{ update, Design, pattern, config, strings: props.strings }}
/>
<div className="tw-flex lg:tw-flex-row tw-grow lg:tw-max-h-[90vh] tw-max-h-[calc(100vh-3rem)] tw-h-full tw-py-2 lg:tw-mt-2">
<div className="lg:tw-w-2/3 tw-flex tw-flex-col tw-h-full tw-grow tw-p-2 tw-shadow tw-mx-2">
<div className="tw:flex tw:lg:flex-row tw:grow tw:lg:max-h-[90vh] tw:max-h-[calc(100vh-3rem)] tw:h-full tw:py-2 tw:lg:mt-2">
<div className="tw:lg:w-2/3 tw:flex tw:flex-col tw:h-full tw:grow tw:p-2 tw:shadow tw:mx-2">
{props.output}
</div>
{state.ui?.aside ? (
<div
className={`tw-hidden xl:tw-block tw-w-1/3 tw-shrink tw-grow-0 lg:tw-p-4 tw-max-w-2xl tw-h-full tw-overflow-scroll`}
className={`tw:hidden tw:xl:block tw:w-1/3 tw:shrink tw:grow-0 tw:lg:p-4 tw:max-w-2xl tw:h-full tw:overflow-scroll`}
>
<h5 className="tw-capitalize">{pattern.designConfig.data.id} Options</h5>
<h5 className="tw:capitalize">{pattern.designConfig.data.id} Options</h5>
<DesignOptionsMenu {...props} />
<h5>Core Settings</h5>
<CoreSettingsMenu {...props} />

View file

@ -46,7 +46,7 @@ export const UserSetPicker = ({
if (!hasSets)
return (
<div className="tw-w-full tw-max-w-3xl tw-mx-auto">
<div className="tw:w-full tw:max-w-3xl tw:mx-auto">
<Popout tip>
<h5> You do not (yet) have any of your own measurements sets</h5>
<p>
@ -56,14 +56,14 @@ export const UserSetPicker = ({
{config.hrefNewSet ? (
<a
href={config.hrefNewSet}
className="tw-daisy-btn tw-daisy-btn-accent tw-capitalize"
className="tw:daisy-btn tw:daisy-btn-accent tw:capitalize"
target="_BLANK"
rel="nofollow"
>
Create a new measurements set
</a>
) : null}
<p className="tw-text-sm">
<p className="tw:text-sm">
Because our patterns are bespoke, we strongly suggest you take accurate measurements.
</p>
</Popout>
@ -73,7 +73,7 @@ export const UserSetPicker = ({
return (
<>
{okSets.length > 0 && (
<div className="tw-grid tw-grid-cols-2 md:tw-grid-cols-4 lg:tw-grid-cols-6 tw-gap-2 tw-mt-4">
<div className="tw:grid tw:grid-cols-2 tw:md:grid-cols-4 tw:lg:grid-cols-6 tw:gap-2 tw:mt-4">
{okSets.map((set) => (
<MsetCard
href={false}
@ -87,13 +87,13 @@ export const UserSetPicker = ({
</div>
)}
{lackingSets.length > 0 ? (
<div className="tw-my-4">
<div className="tw:my-4">
<Popout note>
<h5>
Some of your measurements sets lack the measurements required to generate this pattern
</h5>
</Popout>
<div className="tw-grid tw-grid-cols-2 md:tw-grid-cols-4 lg:tw-grid-cols-6 tw-gap-2">
<div className="tw:grid tw:grid-cols-2 tw:md:grid-cols-4 tw:lg:grid-cols-6 tw:gap-2">
{lackingSets.map((set) => (
<MsetCard
{...{ set, Design }}
@ -154,7 +154,7 @@ export const BookmarkedSetPicker = ({
return (
<>
{okSets.length > 0 && (
<div className="tw-grid tw-grid-cols-2 md:tw-grid-cols-4 lg:tw-grid-cols-6 tw-gap-2">
<div className="tw:grid tw:grid-cols-2 tw:md:grid-cols-4 tw:lg:grid-cols-6 tw:gap-2">
{okSets.map((set) => (
<MsetCard
href={false}
@ -168,14 +168,14 @@ export const BookmarkedSetPicker = ({
</div>
)}
{lackingSets.length > 0 && (
<div className="tw-my-4">
<div className="tw:my-4">
<Popout note>
<h5>
Some of these measurements sets lack the measurements required to generate this
pattern
</h5>
</Popout>
<div className="tw-grid tw-grid-cols-2 md:tw-grid-cols-4 lg:tw-grid-cols-6 tw-gap-2">
<div className="tw:grid tw:grid-cols-2 tw:md:grid-cols-4 tw:lg:grid-cols-6 tw:gap-2">
{lackingSets.map((set) => (
<MsetCard
href={false}
@ -216,7 +216,7 @@ export const CuratedSetPicker = ({ clickHandler }) => {
}, [])
return (
<div className="tw-max-w-7xl">
<div className="tw:max-w-7xl">
<CuratedMeasurementsSetLineup
clickHandler={clickHandler}
sets={orderBy(sets, 'height', 'asc')}
@ -227,9 +227,9 @@ export const CuratedSetPicker = ({ clickHandler }) => {
export const CuratedMeasurementsSetLineup = ({ sets = [], clickHandler }) => (
<div
className={`tw-w-full tw-flex tw-flex-row ${
sets.length > 1 ? 'tw-justify-start tw-px-8' : 'tw-justify-center'
} tw-overflow-x-scroll`}
className={`tw:w-full tw:flex tw:flex-row ${
sets.length > 1 ? 'tw:justify-start tw:px-8' : 'tw:justify-center'
} tw:overflow-x-scroll`}
style={{
backgroundImage: `url(/img/lineup-backdrop.svg)`,
width: 'auto',
@ -240,7 +240,7 @@ export const CuratedMeasurementsSetLineup = ({ sets = [], clickHandler }) => (
{sets.map((set) => {
const props = {
className:
'tw-aspect-[1/3] tw-w-auto tw-h-96 tw-bg-transparent tw-border-0 hover:tw-cursor-pointer hover:tw-bg-secondary/20',
'tw:aspect-1/3 tw:w-auto tw:h-96 tw:bg-transparent tw:border-0 tw:hover:cursor-pointer tw:hover:bg-secondary/20',
style: {
backgroundImage: `url(${cloudflareImageUrl({
id: `cset-${set.id}`,
@ -255,7 +255,7 @@ export const CuratedMeasurementsSetLineup = ({ sets = [], clickHandler }) => (
}
return (
<div className="tw-flex tw-flex-col tw-items-center" key={set.id}>
<div className="tw:flex tw:flex-col tw:items-center" key={set.id}>
<button {...props} key={set.id}></button>
<b>{set.nameEn}</b>
</div>

View file

@ -6,7 +6,7 @@ export const Tooltip = (props) => {
return (
<div
{...rest}
className={`tw-daisy-tooltip tw-daisy-tooltip-bottom before:tw-bg-base-200 before:tw-shadow before:tw-text-base-content`}
className={`tw:daisy-tooltip tw:daisy-tooltip-bottom tw:before:bg-base-200 tw:before:shadow tw:before:text-base-content`}
data-tip={tip}
>
{children}

View file

@ -11,24 +11,24 @@ export const ZoomablePattern = forwardRef(function ZoomablePatternRef(props, ref
const { onTransformed, zoomFunctions, setZoomFunctions } = useContext(ZoomContext)
return (
<div className="tw-relative">
<div className="tw-absolute tw-top-0 tw-right-0 tw-z-20">
<div className="tw-flex tw-flex-row tw-gap-1 tw-items-center">
<div className="tw:relative">
<div className="tw:absolute tw:top-0 tw:right-0 tw:z-20">
<div className="tw:flex tw:flex-row tw:gap-1 tw:items-center">
<button
onClick={() => props.update.ui('rotate', rotate ? 0 : 1)}
className="hover:tw-text-secondary"
className="tw:hover:text-secondary"
>
<RotateIcon className={`tw-h-6 tw-w-6 ${rotate ? 'tw-text-success' : ''}`} />
<RotateIcon className={`tw:h-6 tw:w-6 ${rotate ? 'tw:text-success' : ''}`} />
</button>
<button
onClick={() => (zoomFunctions.zoomIn ? zoomFunctions.zoomIn() : null)}
className="hover:tw-text-secondary"
className="tw:hover:text-secondary"
>
<ZoomInIcon />
</button>
<button
onClick={() => (zoomFunctions.zoomOut ? zoomFunctions.zoomOut() : null)}
className="hover:tw-text-secondary"
className="tw:hover:text-secondary"
>
<ZoomOutIcon />
</button>
@ -53,7 +53,7 @@ export const ZoomablePattern = forwardRef(function ZoomablePatternRef(props, ref
<Pattern
{...{ renderProps, components, strings }}
ref={ref}
className={`freesewing pattern tw-w-full ${rotate ? 'tw--rotate-90' : ''}`}
className={`freesewing pattern tw:w-full ${rotate ? 'tw:-rotate-90' : ''}`}
/>
)}
</TransformComponent>

View file

@ -10,7 +10,7 @@ import { FormControl } from '@freesewing/react/components/Input'
import { MiniTip } from '@freesewing/react/components/Mini'
/** @type {String} class to apply to buttons on open menu items */
const iconButtonClass = 'tw-daisy-btn tw-daisy-btn-xs tw-daisy-btn-ghost tw-px-0 tw-text-accent'
const iconButtonClass = 'tw:daisy-btn tw:daisy-btn-xs tw:daisy-btn-ghost tw:px-0 tw:text-accent'
/**
* A generic component for handling a menu item.
@ -81,15 +81,15 @@ export const MenuItem = ({
}}
>
<EditIcon
className={`tw-w-6 tw-h-6 ${
override ? 'tw-bg-secondary tw-text-secondary-content tw-rounded' : 'tw-text-secondary'
className={`tw:w-6 tw:h-6 ${
override ? 'tw:bg-secondary tw:text-secondary-content tw:rounded' : 'tw:text-secondary'
}`}
/>
</button>
)
const ResetButton = ({ disabled = false }) => (
<button
className={`${iconButtonClass} disabled:tw-bg-opacity-0`}
className={iconButtonClass}
disabled={disabled}
onClick={(evt) => {
evt.stopPropagation()
@ -107,10 +107,10 @@ export const MenuItem = ({
<FormControl
label={false}
id={config.name}
labelBR={<div className="tw-flex tw-flex-row tw-items-center tw-gap-2">{buttons}</div>}
labelBR={<div className="tw:flex tw:flex-row tw:items-center tw:gap-2">{buttons}</div>}
labelBL={
<span
className={`tw-text-base tw-font-medium tw--mt-2 tw-block ${changed ? 'tw-text-accent' : 'tw-opacity-50'}`}
className={`tw:text-base tw:font-medium tw:-mt-2 tw:block ${changed ? 'tw:text-accent' : 'tw:opacity-50'}`}
>
{changed ? 'This is a custom value' : 'This is the default value'}
</span>
@ -190,9 +190,9 @@ export const MenuItemGroup = ({
: () => <span role="img">fixme-icon</span>
const Value = item.isGroup
? () => (
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center tw-font-medium">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center tw:font-medium">
{Object.keys(item).filter((i) => i !== 'isGroup').length}
<OptionsIcon className="tw-w-5 tw-h-5" />
<OptionsIcon className="tw:w-5 tw:h-5" />
</div>
)
: isDesignOptionsGroup
@ -202,14 +202,14 @@ export const MenuItemGroup = ({
: () => <span>¯\_()_/¯</span>
return [
<div className="tw-flex tw-flex-row tw-items-center tw-justify-between tw-w-full" key="a">
<div className="tw-flex tw-flex-row tw-items-center tw-gap-4 tw-w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:justify-between tw:w-full" key="a">
<div className="tw:flex tw:flex-row tw:items-center tw:gap-4 tw:w-full">
<ItemIcon />
<span className="tw-font-medium tw-capitalize">
<span className="tw:font-medium tw:capitalize">
{item.title ? item.title : getItemLabel(i18n, itemName)}
</span>
</div>
<div className="tw-font-bold">
<div className="tw:font-bold">
<Value
current={currentValues[itemName]}
config={item}
@ -275,13 +275,13 @@ export const MenuItemGroup = ({
*/
export const MenuItemTitle = ({ name, current = null, open = false, emoji = '', Icon = false }) => (
<div
className={`tw-flex tw-flex-row tw-gap-1 tw-items-center tw-w-full ${open ? '' : 'tw-justify-between'}`}
className={`tw:flex tw:flex-row tw:gap-1 tw:items-center tw:w-full ${open ? '' : 'tw:justify-between'}`}
>
<span className="tw-font-medium tw-capitalize tw-flex tw-flex-row tw-gap-2">
<span className="tw:font-medium tw:capitalize tw:flex tw:flex-row tw:gap-2">
{Icon ? <Icon /> : <span role="img">{emoji}</span>}
fixme: {name}
</span>
<span className="tw-font-bold">{current}</span>
<span className="tw:font-bold">{current}</span>
</div>
)
@ -318,25 +318,25 @@ export const MenuButtonGroup = ({ structure, Button = false, Design, Icon, i18n
: () => <span role="img">fixme-icon</span>
const Value = item.isGroup
? () => (
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-center tw-font-medium">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-center tw:font-medium">
{Object.keys(item).filter((i) => i !== 'isGroup').length}
<OptionsIcon className="tw-w-5 tw-h-5" />
<OptionsIcon className="tw:w-5 tw:h-5" />
</div>
)
: null
content.push([
<div
className="tw-flex tw-flex-row tw-items-center tw-justify-between tw-w-full tw-pl-0 tw-pr-4 tw-py-2"
className="tw:flex tw:flex-row tw:items-center tw:justify-between tw:w-full tw:pl-0 tw:pr-4 tw:py-2"
key="a"
>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-4 tw-w-full">
<div className="tw:flex tw:flex-row tw:items-center tw:gap-4 tw:w-full">
<ItemIcon />
<span className="tw-font-medium tw-capitalize">
<span className="tw:font-medium tw:capitalize">
{item.title ? item.title : getItemLabel(i18n, itemName)}
</span>
</div>
<div className="tw-font-bold">
<div className="tw:font-bold">
<Value config={item} Design={Design} />
</div>
</div>,
@ -355,7 +355,7 @@ export const MenuButtonGroup = ({ structure, Button = false, Design, Icon, i18n
}
return (
<div className="tw-flex tw-flex-col tw-gap-0.5 tw-ml-4">
<div className="tw:flex tw:flex-col tw:gap-0.5 tw:ml-4">
{content.filter((item) => item !== null)}
</div>
)

View file

@ -13,19 +13,19 @@ export const DraftMenu = ({ Design, pattern, state, update, i18n }) => {
{
t: 'Design Options',
d: 'These options are specific to this design. You can use them to customize your pattern in a variety of ways.',
icon: <OptionsIcon className="tw-w-8 tw-h-8" />,
icon: <OptionsIcon className="tw:w-8 tw:h-8" />,
menu: <DesignOptionsMenu {...menuProps} />,
},
{
t: 'Core Settings',
d: 'These settings are not specific to the design, but instead allow you to customize various parameters of the FreeSewing core library, which generates the design for you.',
icon: <SettingsIcon className="tw-w-8 tw-h-8" />,
icon: <SettingsIcon className="tw:w-8 tw:h-8" />,
menu: <CoreSettingsMenu {...menuProps} />,
},
{
t: 'UI Preferences',
d: 'These preferences control the UI (User Interface) of the pattern editor',
icon: <UiIcon className="tw-w-8 tw-h-8" />,
icon: <UiIcon className="tw:w-8 tw:h-8" />,
menu: <UiPreferencesMenu {...menuProps} />,
},
]
@ -34,11 +34,11 @@ export const DraftMenu = ({ Design, pattern, state, update, i18n }) => {
items.push(
...sections.map((section) => [
<>
<h5 className="tw-flex tw-flex-row tw-gap-2 tw-items-center tw-justify-between tw-w-full tw-font-bold tw-text-lg">
<h5 className="tw:flex tw:flex-row tw:gap-2 tw:items-center tw:justify-between tw:w-full tw:font-bold tw:text-lg">
<span>{section.t}</span>
{section.icon}
</h5>
<p className="tw-text-left">{section.d}</p>
<p className="tw:text-left">{section.d}</p>
</>,
section.menu,
section.name,

View file

@ -36,8 +36,8 @@ export const MenuConstantInput = ({
<input
type={type}
className={`
tw-daisy-input tw-daisy-input-bordered tw-w-full tw-text-base-content
${changed ? 'tw-daisy-input-secondary' : 'tw-daisy-input-accent'}
tw:daisy-input tw:daisy-input-bordered tw:w-full tw:text-base-content
${changed ? 'tw:daisy-input-secondary' : 'tw:daisy-input-accent'}
`}
value={changed ? current : config.dflt}
onChange={(evt) => updateHandler([name], evt.target.value)}
@ -143,16 +143,16 @@ export const MenuListInput = ({
onClick={() => handleChange(entry)}
>
<div
className={`tw-w-full tw-flex ${
className={`tw:w-full tw:flex ${
sideBySide
? 'tw-flex-row tw-justify-between tw-gap-2 tw-items-center'
: 'tw-flex-col tw-items-start'
? 'tw:flex-row tw:justify-between tw:gap-2 tw:items-center'
: 'tw:flex-col tw:items-start'
}`}
>
<div className="tw-font-semibold">{config.choiceTitles[entry]}</div>
<div className="tw:font-semibold">{config.choiceTitles[entry]}</div>
{compact || !config.choiceDescriptions ? null : (
<div
className={`${config.dense ? 'tw-text-sm tw-leading-5 tw-py-1' : 'tw-text-base'} tw-font-normal`}
className={`${config.dense ? 'tw:text-sm tw:leading-5 tw:py-1' : 'tw:text-base'} tw:font-normal`}
>
{config.choiceDescriptions[entry]}
</div>
@ -178,7 +178,7 @@ export const MenuListToggle = ({ config, changed, updateHandler, name }) => {
return (
<input
type="checkbox"
className={`tw-daisy-toggle ${changed ? 'tw-daisy-toggle-accent' : 'tw-daisy-toggle-secondary'}`}
className={`tw:daisy-toggle ${changed ? 'tw:daisy-toggle-accent' : 'tw:daisy-toggle-secondary'}`}
checked={checked}
onChange={doToggle}
onClick={(evt) => evt.stopPropagation()}
@ -296,7 +296,7 @@ export const MenuSliderInput = ({
if (override)
return (
<>
<div className="tw-flex tw-flex-row tw-justify-between">
<div className="tw:flex tw:flex-row tw:justify-between">
<MenuEditOption
{...{
config,
@ -314,17 +314,17 @@ export const MenuSliderInput = ({
return (
<>
<div className="tw-flex tw-flex-row tw-justify-between">
<span className="tw-opacity-50">
<div className="tw:flex tw:flex-row tw:justify-between">
<span className="tw:opacity-50">
<span dangerouslySetInnerHTML={{ __html: valFormatter(min) + suffix }} />
</span>
<div
className={`tw-font-bold ${val === config.dflt ? 'tw-text-secondary' : 'tw-text-accent'}`}
className={`tw:font-bold ${val === config.dflt ? 'tw:text-secondary' : 'tw:text-accent'}`}
>
<span dangerouslySetInnerHTML={{ __html: valFormatter(val) + suffix }} />
{typeof config.toAbs === 'function' ? (
<span>
<span className="tw-px-2">|</span>
<span className="tw:px-2">|</span>
<span
dangerouslySetInnerHTML={{
__html: formatMm(
@ -340,7 +340,7 @@ export const MenuSliderInput = ({
</span>
) : null}
</div>
<span className="tw-opacity-50">
<span className="tw:opacity-50">
<span dangerouslySetInnerHTML={{ __html: valFormatter(max) + suffix }} />
</span>
</div>
@ -349,8 +349,8 @@ export const MenuSliderInput = ({
{...{ min, max, value: val, step: config.step || 0.1 }}
onChange={(evt) => handleChange(evt.target.value)}
className={`
tw-daisy-range tw-daisy-range-sm tw-mt-1
${changed ? 'tw-daisy-range-accent' : 'tw-daisy-range-secondary'}
tw:daisy-range tw:daisy-range-sm tw:mt-1
${changed ? 'tw:daisy-range-accent' : 'tw:daisy-range-secondary'}
`}
/>
{children}
@ -396,21 +396,21 @@ export const MenuEditOption = (props) => {
return <p>This design option type does not have a component to handle manual input.</p>
return (
<div className="tw-daisy-form-control tw-mb-2 tw-w-full">
<div className="tw-daisy-label tw-font-medium tw-text-accent">
<label className="tw-daisy-label-text">
<div className="tw:daisy-form-control tw:mb-2 tw:w-full">
<div className="tw:daisy-label tw:font-medium tw:text-accent">
<label className="tw:daisy-label-text">
<em>Enter a custom value</em>
</label>
{type === 'pct' && typeof config.fromAbs === 'function' ? (
<label className="tw-daisy-label-text">
<label className="tw:daisy-label-text">
<KeyVal k="units" val={units} onClick={toggleInputUnits} color="secondary" />
</label>
) : null}
</div>
<label className="tw-daisy-input-group tw-daisy-input-group-sm tw-flex tw-flex-row tw-items-end tw-gap-2 tw--mt-4">
<label className="tw:daisy-input-group tw:daisy-input-group-sm tw:flex tw:flex-row tw:items-end tw:gap-2 tw:-mt-4">
<NumberInput value={manualEdit} update={setManualEdit} />
<button
className="tw-daisy-btn tw-daisy-btn-secondary tw-mt-4"
className="tw:daisy-btn tw:daisy-btn-secondary tw:mt-4"
onClick={() => onUpdate(manualEdit, units)}
>
<ApplyIcon />
@ -470,8 +470,8 @@ export const MenuOnlySettingInput = (props) => {
const [design, name] = part.split('.')
config.choiceTitles[part] = (
<span>
<span className="tw-font-medium tw-opacity-80 tw-capitalize">{design}</span>
<span className="tw-font-medium tw-opacity-80 tw-capitalize tw-px-2">&raquo;</span>
<span className="tw:font-medium tw:opacity-80 tw:capitalize">{design}</span>
<span className="tw:font-medium tw:opacity-80 tw:capitalize tw:px-2">&raquo;</span>
{i18n[design].en.p[name]}
</span>
)

View file

@ -29,7 +29,7 @@ export const LayoutSettingsMenu = ({ update, state, Design }) => {
orientation: ({ current, changed }) => (
<MenuHighlightValue changed={changed}>
<PatternIcon
className={`tw-w-6 tw-h-6 tw-text-inherit ${current === 'landscape' ? 'tw--rotate-90' : ''}`}
className={`tw:w-6 tw:h-6 tw:text-inherit ${current === 'landscape' ? 'tw:-rotate-90' : ''}`}
/>
</MenuHighlightValue>
),
@ -67,8 +67,8 @@ const PrintActions = ({ state, update }) => (
<SubAccordion
items={[
[
<div className="tw-w-full tw-flex tw-flex-row tw-gap2 tw-justify-between" key={1}>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-2">
<div className="tw:w-full tw:flex tw:flex-row tw:gap2 tw:justify-between" key={1}>
<div className="tw:flex tw:flex-row tw:items-center tw:gap-2">
<LeftRightIcon />
<span>{'workbench:partTransfo'}</span>
</div>
@ -78,7 +78,7 @@ const PrintActions = ({ state, update }) => (
key={2}
update={() => update.state.ui('hideMovableButtons', state.ui.hideMovableButtons ? false : true)}
label={
<span className="tw-text-base tw-font-normal">{'workbench:partTransfoDesc'}</span>
<span className="tw:text-base tw:font-normal">{'workbench:partTransfoDesc'}</span>
}
list={[
{
@ -97,8 +97,8 @@ const PrintActions = ({ state, update }) => (
'partTransfo',
],
[
<div className="tw-w-full tw-flex tw-flex-row tw-gap2 tw-justify-between" key={1}>
<div className="tw-flex tw-flex-row tw-items-center tw-gap-2">
<div className="tw:w-full tw:flex tw:flex-row tw:gap2 tw:justify-between" key={1}>
<div className="tw:flex tw:flex-row tw:items-center tw:gap-2">
<ResetIcon />
<span>{'workbench:resetPrintLayout'}</span>
</div>
@ -108,7 +108,7 @@ const PrintActions = ({ state, update }) => (
<Fragment key={2}>
<p>{'workbench:resetPrintLayoutDesc'}</p>
<button
className={`${horFlexClasses} tw-btn tw-btn-warning tw-btn-outline tw-w-full`}
className={`${horFlexClasses} tw:btn tw:btn-warning tw:btn-outline tw:w-full`}
onClick={() => update.ui(['layouts', 'print'])}
>
<ResetIcon />

View file

@ -81,12 +81,12 @@ export const TestMeasurementsMenu = ({ Design, state, update }) => {
const SampleOptionButton = ({ name, i18n, update }) => (
<button
className={
'tw-daisy-btn tw-daisy-btn-outline tw-daisy-btn-sm tw-mx-2 ' +
'tw-daisy-btn-secondary tw-flex tw-flex-row tw-items-center tw-justify-between'
'tw:daisy-btn tw:daisy-btn-outline tw:daisy-btn-sm tw:mx-2 ' +
'tw:daisy-btn-secondary tw:flex tw:flex-row tw:items-center tw:justify-between'
}
onClick={() => update.settings('sample', { type: 'option', option: name })}
>
<BeakerIcon className="tw-w-5 tw-h-5" />
<BeakerIcon className="tw:w-5 tw:h-5" />
<span>{i18n.en.o[name].t}</span>
</button>
)
@ -94,12 +94,12 @@ const SampleOptionButton = ({ name, i18n, update }) => (
const SampleMeasurementButton = ({ name, i18n, update }) => (
<button
className={
'tw-daisy-btn tw-daisy-btn-outline tw-daisy-btn-sm tw-mx-2 ' +
'tw-daisy-btn-secondary tw-flex tw-flex-row tw-items-center tw-justify-between'
'tw:daisy-btn tw:daisy-btn-outline tw:daisy-btn-sm tw:mx-2 ' +
'tw:daisy-btn-secondary tw:flex tw:flex-row tw:items-center tw:justify-between'
}
onClick={() => update.settings('sample', { type: 'option', option: name })}
>
<BeakerIcon className="tw-w-5 tw-h-5" />
<BeakerIcon className="tw:w-5 tw:h-5" />
<span>{measurementsTranslations[name]}</span>
</button>
)

View file

@ -50,7 +50,7 @@ export const MenuDegOptionValue = ({ config, current, changed }) => (
* @param {Function} children - The React children
*/
export const MenuHighlightValue = ({ changed, children }) => (
<span className={changed ? 'tw-text-accent' : ''}> {children} </span>
<span className={changed ? 'tw:text-accent' : ''}> {children} </span>
)
/**

View file

@ -9,7 +9,7 @@ import { Collection } from '@freesewing/react/components/Collection'
* @param {Object} update - ViewWrapper state update object
*/
export const DesignsView = ({ designs = {}, update }) => (
<div className="tw-text-center tw-mt-8 tw-mb-24 tw-p-2 lg: tw-p-8">
<div className="tw:text-center tw:mt-8 tw:mb-24 tw:p-2 lg: tw:p-8">
<h1>Choose a design from the FreeSewing collection</h1>
<Collection
editor

View file

@ -19,11 +19,11 @@ export const DocsView = ({ state, config, update }) => {
return (
<>
<HeaderMenu state={state} {...{ config, update }} />
<div className="tw-m-auto tw-mt-8 tw-max-w-2xl tw-px-4 tw-mb-8">
<div className="tw:m-auto tw:mt-8 tw:max-w-2xl tw:px-4 tw:mb-8">
<H1>Documenation</H1>
<Popout link>
<H5>Understanding the FreeSewing Pattern Editor</H5>
<p className="tw-text-lg">
<p className="tw:text-lg">
Please refer to the pattern editor documentation at:
<br />
<b>

View file

@ -33,21 +33,21 @@ export const DraftErrorHandler = ({ failure, errors }) => {
<Link href="https://codeberg.org/freesewing/freesewing/issues">report an issue</Link>.
</p>
<div className={'tw-mt-4'}>
<div className={'tw:mt-4'}>
<button
className={`tw-daisy-btn tw-daisy-btn-primary`}
className={`tw:daisy-btn tw:daisy-btn-primary`}
onClick={() => setExpanded(!expanded)}
>
<ExpandIcon />
Show error details
</button>
<button className={`tw-daisy-btn tw-ml-4`} onClick={() => setHidden(true)}>
<button className={`tw:daisy-btn tw:ml-4`} onClick={() => setHidden(true)}>
<CloseIcon />
Hide
</button>
</div>
{expanded ? (
<div className={'tw-mt-8'}>
<div className={'tw:mt-8'}>
{failure ? <LogEntry key="failure" logEntry={failure} /> : null}
{errors.map((line, i) => (
<LogEntry key={i} logEntry={line} />

View file

@ -65,7 +65,7 @@ export const DraftView = ({ Design, state, update, config, plugins = [], PluginO
<DraftErrorHandler {...{ failure, errors }} />
<PluginOutput {...{ pattern, Design, state, update, config }} />
<ZoomablePattern update={update}>
<div className="tw-w-full tw-h-full" dangerouslySetInnerHTML={{ __html }} />
<div className="tw:w-full tw:h-full" dangerouslySetInnerHTML={{ __html }} />
</ZoomablePattern>
</>
)

View file

@ -27,9 +27,9 @@ export const EditSettingsView = (props) => {
return (
<>
<HeaderMenu state={state} {...{ config, update }} />
<div className="tw-m-auto tw-mt-8 tw-max-w-4xl tw-px-4 tw-mb-8">
<div className="tw:m-auto tw:mt-8 tw:max-w-4xl tw:px-4 tw:mb-8">
<H1>Edit settings by hand</H1>
<p className="tw-mb-4">
<p className="tw:mb-4">
You can hand-edit your pattern settings below.
<br />
The changes will not take effect until you click the <b>Save Settings</b> button at the
@ -106,22 +106,22 @@ export const PrimedSettingsEditor = (props) => {
<>
<H4>You have made changes</H4>
<p>Your settings have been edited, and are now different from the editor settings.</p>
<div className="tw-grid tw-grid-cols-1 lg:tw-grid-cols-3 tw-gap-2 tw-w-full">
<div className="tw:grid tw:grid-cols-1 tw:lg:grid-cols-3 tw:gap-2 tw:w-full">
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline"
className="tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-outline"
onClick={() => setShowDelta(!showDelta)}
>
{showDelta ? 'Hide' : 'Show'} Changes
</button>
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-flex tw-flex-row tw-items-center tw-justify-between"
className="tw:daisy-btn tw:daisy-btn-primary tw:flex tw:flex-row tw:items-center tw:justify-between"
onClick={save}
>
<OkIcon stroke={3} />
Save Settings
</button>
<button
className="tw-daisy-btn tw-daisy-btn-error tw-daisy-btn-outline tw-flex tw-flex-row tw-items-center tw-justify-between"
className="tw:daisy-btn tw:daisy-btn-error tw:daisy-btn-outline tw:flex tw:flex-row tw:items-center tw:justify-between"
onClick={revert}
>
<ResetIcon />
@ -129,7 +129,7 @@ export const PrimedSettingsEditor = (props) => {
</button>
</div>
{showDelta ? (
<div className="tw-my-4 tw-w-full tw-overflow-scroll">
<div className="tw:my-4 tw:w-full tw:overflow-scroll">
<DiffViewer
oldValue={yaml.stringify(state.settings)}
newValue={yaml.stringify(settings)}

View file

@ -52,11 +52,11 @@ export const ExportView = (props) => {
return (
<>
<HeaderMenu state={state} {...{ config, update }} />
<div className="tw-m-auto tw-mt-8 tw-max-w-2xl tw-px-4 tw-mb-8">
<div className="tw:m-auto tw:mt-8 tw:max-w-2xl tw:px-4 tw:mb-8">
<H1>Export Pattern</H1>
<H2>Share your pattern</H2>
<p>If you merely want to share your pattern with others, you can copy these URLs:</p>
<div className="tw-grid tw-grid-cols-1 lg:tw-grid-cols-2 tw-gap-2 tw-mt-2 ">
<div className="tw:grid tw:grid-cols-1 tw:lg:grid-cols-2 tw:gap-2 tw:mt-2 ">
<CopyToClipboardButton content={urls.a} update={update}>
Pattern and Measurements
</CopyToClipboardButton>
@ -64,11 +64,11 @@ export const ExportView = (props) => {
Pattern only
</CopyToClipboardButton>
</div>
<details className="tw-pt-2">
<details className="tw:pt-2">
<summary>
<span className={linkClasses}>Explain these buttons</span>
</summary>
<div className="tw-ml-4 tw-border-l-2 tw-pl-4">
<div className="tw:ml-4 tw:border-l-2 tw:pl-4">
<H5>Pattern and Measurements</H5>
<p>
Use the <b>Pattern and Measurements</b> URL to share this pattern exactly as-is,
@ -77,8 +77,8 @@ export const ExportView = (props) => {
<Highlight noCopy title="URL" language="URL">
{urls.a}
</Highlight>
<div className="tw-text-sm tw--mt-3 tw-flex tw-flex-row tw-gap-2 tw-items-center tw-pl-4 tw-mb-4">
<TipIcon className="tw-w-5 tw-h-5 tw-text-success" />
<div className="tw:text-sm tw:-mt-3 tw:flex tw:flex-row tw:gap-2 tw:items-center tw:pl-4 tw:mb-4">
<TipIcon className="tw:w-5 tw:h-5 tw:text-success" />
Use this to allow others to troubleshoot your pattern.
</div>
<H5>Pattern only</H5>
@ -88,20 +88,20 @@ export const ExportView = (props) => {
<Highlight noCopy title="URL" language="URL">
{urls.b}
</Highlight>
<div className="tw-text-sm tw--mt-3 tw-flex tw-flex-row tw-gap-2 tw-items-center tw-pl-4">
<TipIcon className="tw-w-5 tw-h-5 tw-text-success" />
<div className="tw:text-sm tw:-mt-3 tw:flex tw:flex-row tw:gap-2 tw:items-center tw:pl-4">
<TipIcon className="tw:w-5 tw:h-5 tw:text-success" />
Use this to allow others to recreate this pattern for themselves.
</div>
</div>
</details>
<H2>Export for printing</H2>
<p>You can export your pattern in a variety of page formats for printing:</p>
<div className="tw-grid tw-grid-cols-1 lg:tw-grid-cols-2 tw-gap-2">
<div className="tw-flex tw-flex-col tw-gap-2 tw-max-w-md">
<div className="tw:grid tw:grid-cols-1 tw:lg:grid-cols-2 tw:gap-2">
<div className="tw:flex tw:flex-col tw:gap-2 tw:max-w-md">
<H3>ISO paper sizes</H3>
{['a4', 'a3', 'a2', 'a1', 'a0'].map((format) => (
<button
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-primary tw-uppercase`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-primary tw:uppercase`}
onClick={() => exportPattern({ ...exportProps, format })}
>
<PrintIcon />
@ -109,11 +109,11 @@ export const ExportView = (props) => {
</button>
))}
</div>
<div className="tw-flex tw-flex-col tw-gap-2 tw-max-w-md">
<div className="tw:flex tw:flex-col tw:gap-2 tw:max-w-md">
<H3>Other paper sizes</H3>
{['letter', 'legal', 'tabloid'].map((format) => (
<button
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-primary tw-uppercase`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-primary tw:uppercase`}
onClick={() => exportPattern({ ...exportProps, format })}
>
<PrintIcon />
@ -126,10 +126,10 @@ export const ExportView = (props) => {
<p>
We recommend SVG for editing, but we also provide a full-sized PDF if you prefer that.
</p>
<div className="tw-grid tw-grid-cols-1 lg:tw-grid-cols-2 tw-gap-2 tw-mt-2">
<div className="tw:grid tw:grid-cols-1 tw:lg:grid-cols-2 tw:gap-2 tw:mt-2">
{['svg', 'pdf'].map((format) => (
<button
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-primary tw-uppercase`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-primary tw:uppercase`}
onClick={() => exportPattern({ ...exportProps, format })}
>
<EditIcon />
@ -139,10 +139,10 @@ export const ExportView = (props) => {
</div>
<H2>Export as code</H2>
<p>This is all you need to reconstruct this pattern using FreeSewing&apos; software:</p>
<div className="tw-grid tw-grid-cols-1 lg:tw-grid-cols-2 tw-gap-2 tw-mt-2">
<div className="tw:grid tw:grid-cols-1 tw:lg:grid-cols-2 tw:gap-2 tw:mt-2">
{['json', 'yaml'].map((format) => (
<button
className={`${horFlexClasses} tw-daisy-btn tw-daisy-btn-primary tw-uppercase`}
className={`${horFlexClasses} tw:daisy-btn tw:daisy-btn-primary tw:uppercase`}
onClick={() => exportPattern({ ...exportProps, format })}
>
<CodeIcon />

View file

@ -68,7 +68,7 @@ export const InspectView = ({ Design, state, update, config }) => {
<Xray
renderProps={renderProps}
drillProps={{ info }}
className={`freesewing pattern tw-w-full ${state.ui?.rotate ? 'tw--rotate-90' : ''}`}
className={`freesewing pattern tw:w-full ${state.ui?.rotate ? 'tw:-rotate-90' : ''}`}
strings={strings}
/>
</ZoomablePattern>

View file

@ -3,7 +3,7 @@ import Markdown from 'react-markdown'
export const LogEntry = ({ logEntry }) => (
<>
<div className="log-entry tw-mb-2">
<div className="log-entry tw:mb-2">
<Markdown>{Array.isArray(logEntry) ? logEntry[0] : logEntry}</Markdown>
</div>
{/* uncomment to enable stacktrace view

View file

@ -26,7 +26,7 @@ export const LogView = (props) => {
return (
<>
<HeaderMenu state={state} {...{ config, update }} />
<div className="tw-m-auto tw-mt-8 tw-max-w-2xl tw-px-4 tw-mb-8">
<div className="tw:m-auto tw:mt-8 tw:max-w-2xl tw:px-4 tw:mb-8">
<H1>Pattern Logs</H1>
<Tabs tabs="Set 0 Logs, Pattern Logs">
<Tab tabId="Set 0 Logs">

View file

@ -22,7 +22,7 @@ import { HeaderMenu } from '../HeaderMenu.mjs'
import { H1, H5 } from '@freesewing/react/components/Heading'
const iconClasses = {
className: 'tw-w-8 tw-h-8 md:tw-w-10 md:tw-h-10 lg:tw-w-12 lg:tw-h-12 tw-shrink-0',
className: 'tw:w-8 tw:h-8 tw:md:w-10 tw:md:h-10 tw:lg:w-12 tw:lg:h-12 tw:shrink-0',
stroke: 1.5,
}
@ -77,13 +77,13 @@ export const MeasurementsView = ({
// User measurement set
update.settings(['metadata'], { setName: set.name })
update.notifySuccess(
<div className="tw-flex tw-flex-row tw-items-center tw-justify-between tw-w-full tw-flex-wrap tw-gap-2">
<div className="tw:flex tw:flex-row tw:items-center tw:justify-between tw:w-full tw:flex-wrap tw:gap-2">
<span>Measurements loaded</span>
<button
className="tw-daisy-btn tw-daisy-btn-success tw-daisy-btn-outline tw-border-white"
className="tw:daisy-btn tw:daisy-btn-success tw:daisy-btn-outline tw:border-white"
onClick={() => update.view('draft')}
>
<span className="tw-text-white">Load Draft View</span>
<span className="tw:text-white">Load Draft View</span>
</button>
</div>
)
@ -95,11 +95,11 @@ export const MeasurementsView = ({
items.push(
[
<Fragment key={1}>
<div className={`${horFlexClasses} tw-w-full`}>
<div className={`${horFlexClasses} tw:w-full`}>
<H5 id="ownsets">Choose one of your own measurements sets</H5>
<MeasurementsSetIcon {...iconClasses} />
</div>
<p className="tw-text-left">
<p className="tw:text-left">
Pick any of your own measurements sets that have all required measurements to generate
this pattern.
</p>
@ -115,11 +115,11 @@ export const MeasurementsView = ({
],
[
<Fragment key={1}>
<div className={`${horFlexClasses} tw-w-full`}>
<div className={`${horFlexClasses} tw:w-full`}>
<H5 id="bookmarkedsets">Choose one of the measurements sets you have bookmarked</H5>
<BookmarkIcon {...iconClasses} />
</div>
<p className="tw-text-left">
<p className="tw:text-left">
If you have bookmarked any measurements sets, you can select from those too.
</p>
</Fragment>,
@ -134,11 +134,11 @@ export const MeasurementsView = ({
],
[
<Fragment key={1}>
<div className={`${horFlexClasses} tw-w-full`}>
<div className={`${horFlexClasses} tw:w-full`}>
<H5 id="curatedsets">Choose one of FreeSewing&apos;s curated measurements sets</H5>
<CuratedMeasurementsSetIcon {...iconClasses} />
</div>
<p className="tw-text-left">
<p className="tw:text-left">
If you&apos;re just looking to try out our platform, you can select from our list of
curated measurements sets.
</p>
@ -148,11 +148,11 @@ export const MeasurementsView = ({
],
[
<Fragment key={1}>
<div className={`${horFlexClasses} tw-w-full`}>
<div className={`${horFlexClasses} tw:w-full`}>
<H5 id="loadid">Load a measurements set by ID</H5>
<FingerprintIcon {...iconClasses} />
</div>
<p className="tw-text-left">
<p className="tw:text-left">
If you know the ID of a measurements set either one of your own or a public set we
can load it for you.
</p>
@ -164,11 +164,11 @@ export const MeasurementsView = ({
// Manual editing is always an option
items.push([
<Fragment key={1}>
<div className={`${horFlexClasses} tw-w-full`}>
<div className={`${horFlexClasses} tw:w-full`}>
<H5 id="editmeasurements">Edit measurements by hand</H5>
<EditIcon {...iconClasses} />
</div>
<p className="tw-text-left">You can manually set or override measurements below.</p>
<p className="tw:text-left">You can manually set or override measurements below.</p>
</Fragment>,
<MeasurementsEditor
key={2}
@ -180,7 +180,7 @@ export const MeasurementsView = ({
return (
<>
<HeaderMenu state={state} {...{ config, update }} />
<div className="tw-max-w-7xl tw-mt-8 tw-mx-auto tw-px-4 tw-mb-4">
<div className="tw:max-w-7xl tw:mt-8 tw:mx-auto tw:px-4 tw:mb-4">
<H1>Measurements</H1>
{missingMeasurements && missingMeasurements.length > 0 ? (
<Popout note dense noP>
@ -188,11 +188,11 @@ export const MeasurementsView = ({
To generate this pattern, we need {missingMeasurements.length} additional measurement
{missingMeasurements.length === 1 ? '' : 's'}:
</h3>
<ol className="tw-list tw-list-inside tw-flex tw-flex-row tw-flex-wrap tw-ml-0 tw-pl-0">
<ol className="tw:list tw:list-inside tw:flex tw:flex-row tw:flex-wrap tw:ml-0 tw:pl-0">
{missingMeasurements.map((m, i) => (
<li key={i} className="tw-flex">
{i > 0 ? <span className="tw-pr-2">,</span> : null}
<span className="tw-font-medium">{measurementsTranslations[m]}</span>
<li key={i} className="tw:flex">
{i > 0 ? <span className="tw:pr-2">,</span> : null}
<span className="tw:font-medium">{measurementsTranslations[m]}</span>
</li>
))}
</ol>
@ -200,15 +200,15 @@ export const MeasurementsView = ({
) : (
<Popout tip dense noP>
<H5>We have all required measurements to draft this pattern</H5>
<div className="tw-flex tw-flex-row tw-flex-wrap tw-gap-2 tw-mt-2">
<div className="tw:flex tw:flex-row tw:flex-wrap tw:gap-2 tw:mt-2">
<button
className="tw-daisy-btn tw-daisy-btn-primary"
className="tw:daisy-btn tw:daisy-btn-primary"
onClick={() => update.view('draft')}
>
Draft Pattern
</button>
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline"
className="tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-outline"
onClick={() => update.view('picker')}
>
Choose a different view
@ -228,7 +228,7 @@ const LoadMeasurementsSetById = ({ loadMeasurements, update }) => {
return (
<div>
<div className="tw-flex tw-flex-row tw-gap-2 tw-items-end">
<div className="tw:flex tw:flex-row tw:gap-2 tw:items-end">
<NumberInput
label="Measurements Set ID"
update={setId}
@ -236,7 +236,7 @@ const LoadMeasurementsSetById = ({ loadMeasurements, update }) => {
valid={(val) => Number(val) == val}
/>
<button
className="tw-daisy-btn tw-daisy-btn-primary"
className="tw:daisy-btn tw:daisy-btn-primary"
onClick={() => loadMeasurementsSet(id, backend, loadMeasurements, update)}
>
Load set
@ -256,13 +256,13 @@ async function loadMeasurementsSet(id, backend, loadMeasurements, update) {
loadMeasurements(result[1].set)
update.clearLoading()
update.notifySuccess(
<div className="tw-flex tw-flex-row tw-items-center tw-justify-between tw-w-full tw-flex-wrap tw-gap-2">
<div className="tw:flex tw:flex-row tw:items-center tw:justify-between tw:w-full tw:flex-wrap tw:gap-2">
<span>Measurements set loaded</span>
<button
className="tw-daisy-btn tw-daisy-btn-success tw-daisy-btn-outline tw-border-white"
className="tw:daisy-btn tw:daisy-btn-success tw:daisy-btn-outline tw:border-white"
onClick={() => update.view('draft')}
>
<span className="tw-text-white">Load Draft View</span>
<span className="tw:text-white">Load Draft View</span>
</button>
</div>
)

View file

@ -92,7 +92,7 @@ export const SaveView = ({ config, state, update }) => {
return (
<RoleBlock user>
<HeaderMenu state={state} {...{ config, update }} />
<div className="tw-m-auto tw-mt-8 tw-max-w-2xl tw-px-4">
<div className="tw:m-auto tw:mt-8 tw:max-w-2xl tw:px-4">
{saveAs && saveAs.pattern ? (
<>
<h2>Save Pattern</h2>
@ -103,16 +103,16 @@ export const SaveView = ({ config, state, update }) => {
</Popout>
)}
<button
className={`${classeshorFlexNoSm} tw-btn tw-btn-primary tw-btn-lg tw-w-full tw-mt-2 tw-my-8`}
className={`${classeshorFlexNoSm} tw:btn tw:btn-primary tw:btn-lg tw:w-full tw:mt-2 tw:my-8`}
onClick={savePattern}
>
<SaveIcon className="tw-h-8 tw-w-8" />
<SaveIcon className="tw:h-8 tw:w-8" />
Save Patter #{saveAs.pattern}
</button>
</>
) : null}
<H1>Save As New Pattern</H1>
<div className="tw-mb-4">
<div className="tw:mb-4">
<StringInput
label="Pattern title"
current={name}
@ -121,20 +121,20 @@ export const SaveView = ({ config, state, update }) => {
labelBR={
<>
{withNotes ? (
<div className="tw-flex tw-flex-row tw-items-center tw-gap-4">
<div className="tw:flex tw:flex-row tw:items-center tw:gap-4">
<button
className={`tw-font-bold ${linkClasses}`}
className={`tw:font-bold ${linkClasses}`}
onClick={() => setWithNotes(false)}
>
Hide notes
</button>
<button className={`tw-font-bold ${linkClasses}`} onClick={addSettingsToNotes}>
<button className={`tw:font-bold ${linkClasses}`} onClick={addSettingsToNotes}>
Add settings to notes
</button>
</div>
) : (
<button
className={`tw-font-bold ${linkClasses}`}
className={`tw:font-bold ${linkClasses}`}
onClick={() => setWithNotes(true)}
>
Add notes
@ -150,24 +150,24 @@ export const SaveView = ({ config, state, update }) => {
update={setNotes}
/>
) : null}
<div className="tw-flex tw-flex-row tw-gap-2 tw-mt-8">
<div className="tw:flex tw:flex-row tw:gap-2 tw:mt-8">
<button
className={`tw-daisy-btn tw-daisy-btn-primary lg:tw-daisy-btn-lg tw-daisy-btn-outline`}
className={`tw:daisy-btn tw:daisy-btn-primary lg:tw:daisy-btn-lg tw:daisy-btn-outline`}
onClick={update.viewBack}
title="Cancel"
>
<span>Cancel</span>
</button>
<button
className={`tw-flex tw-flex-row tw-items-center tw-justify-between tw-daisy-btn tw-daisy-btn-primary lg:tw-daisy-btn-lg tw-grow`}
className={`tw:flex tw:flex-row tw:items-center tw:justify-between tw:daisy-btn tw:daisy-btn-primary lg:tw:daisy-btn-lg tw:grow`}
onClick={saveAsNewPattern}
title="Save as new pattern"
>
<SaveAsIcon className="tw-w-8 tw-h-8" />
<SaveAsIcon className="tw:w-8 tw:h-8" />
<span>Save as new pattern</span>
</button>
</div>
<p className="tw-text-sm tw-text-right">
<p className="tw:text-sm tw:text-right">
To access your saved patterns, go to:
<b>
{' '}

View file

@ -92,22 +92,22 @@ export const TestView = ({ Design, state, update, config }) => {
return (
<>
<HeaderMenu state={state} {...{ config, update, Design }} />
<div className="tw-m-auto tw-mt-8 tw-max-w-4xl tw-px-4 tw-mb-8">
<div className="tw:m-auto tw:mt-8 tw:max-w-4xl tw:px-4 tw:mb-8">
<H1>Test Pattern</H1>
<div className="tw-grid tw-grid-cols-1 lg:tw-grid-cols-2 lg:tw-gap-4">
<div className="tw-flex tw-flex-col tw-gap-4">
<div className="tw:grid tw:grid-cols-1 tw:lg:grid-cols-2 tw:lg:gap-4">
<div className="tw:flex tw:flex-col tw:gap-4">
<H3>Test Design Options</H3>
<SampleOptionsMenu {...{ Design, state, update }} />
</div>
{trm.length > 0 ? (
<div className="tw-flex tw-flex-col tw-gap-4">
<div className="tw:flex tw:flex-col tw:gap-4">
<H3>Test Measurements</H3>
<H4>Required Measurements</H4>
<div className="">
{trm.map(({ t, m }) => (
<button
key={m}
className="tw-my-0.5 tw-block tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline tw-daisy-btn-xs"
className="tw:my-0.5 tw:block tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-outline tw:daisy-btn-xs"
onClick={() =>
update.settings(['sample'], { type: 'measurement', measurement: m })
}
@ -117,13 +117,13 @@ export const TestView = ({ Design, state, update, config }) => {
))}
</div>
{tom.length > 0 ? (
<div className="tw-flex tw-flex-col tw-gap-4">
<div className="tw:flex tw:flex-col tw:gap-4">
<H4>Optional Measurements</H4>
<div className="">
{tom.map(({ t, m }) => (
<button
key={m}
className="tw-my-0.5 tw-block tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline tw-daisy-btn-xs"
className="tw:my-0.5 tw:block tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-outline tw:daisy-btn-xs"
onClick={() =>
update.settings(['sample'], { type: 'measurement', measurement: m })
}
@ -175,7 +175,7 @@ const SampleOptionsSubMenu = ({ structure, update, level = 1 }) => {
output.push(
<button
key={name}
className="tw-my-0.5 tw-block tw-daisy-btn tw-daisy-btn-primary tw-daisy-btn-outline tw-daisy-btn-xs"
className="tw:my-0.5 tw:block tw:daisy-btn tw:daisy-btn-primary tw:daisy-btn-outline tw:daisy-btn-xs"
onClick={() => update.settings(['sample'], { type: 'option', option: name })}
>
{struct.title}
@ -188,7 +188,7 @@ const SampleOptionsSubMenu = ({ structure, update, level = 1 }) => {
if (struct.isGroup) {
output.push(
<H5 key={name}>
<span className="tw-capitalize">{name}</span>
<span className="tw:capitalize">{name}</span>
</H5>
)
output.push(
@ -202,5 +202,5 @@ const SampleOptionsSubMenu = ({ structure, update, level = 1 }) => {
}
}
return <div className="tw-pl-2 tw-border-l-2">{output}</div>
return <div className="tw:pl-2 tw:border-l-2">{output}</div>
}

View file

@ -22,16 +22,16 @@ export const UndosView = ({ Design, update, state, config }) => {
return (
<>
<HeaderMenu {...{ update, Design, config, state }} />
<div className="tw-text-left tw-mt-8 tw-mb-24 tw-px-4 tw-max-w-xl tw-mx-auto">
<div className="tw:text-left tw:mt-8 tw:mb-24 tw:px-4 tw:max-w-xl tw:mx-auto">
<H1>Undo History</H1>
<p className="tw-mb-4">Time-travel through your recent pattern changes.</p>
<p className="tw:mb-4">Time-travel through your recent pattern changes.</p>
{steps.length < 1 ? (
<Popout note>
<h4>Your undo history is currently empty</h4>
<p>When you make changes to your pattern, they will show up here.</p>
<p>For example, you can click the button below to change the pattern rotation:</p>
<button
className="tw-daisy-btn tw-daisy-btn-primary tw-capitalize"
className="tw:daisy-btn tw:daisy-btn-primary tw:capitalize"
onClick={() => update.settings('ui.rotate', state.settings?.ui?.rotate ? 0 : 1)}
>
Example: Rotate pattern
@ -43,7 +43,7 @@ export const UndosView = ({ Design, update, state, config }) => {
<MiniTip>
Click on any change to undo all changes up to, and including, that change.
</MiniTip>
<div className="tw-flex tw-flex-col tw-gap-2 tw-mt-4">
<div className="tw:flex tw:flex-col tw:gap-2 tw:mt-4">
{steps.map((step, index) => (
<UndoStep key={step.time} {...{ step, update, state, Design, index }} />
))}
@ -97,8 +97,8 @@ export const UndoStep = ({ update, state, step, Design, compact = false, index =
if (compact)
return (
<ButtonFrame dense onClick={() => update.restore(index, state._)}>
<div className="tw-flex tw-flex-row tw-items-center tw-align-start tw-gap-2 tw-w-full">
<UndoIcon text={index} className="tw-w-5 tw-h-5 tw-text-secondary" />
<div className="tw:flex tw:flex-row tw:items-center tw:align-start tw:gap-2 tw:w-full">
<UndoIcon text={index} className="tw:w-5 tw:h-5 tw:text-secondary" />
{data.msg ? data.msg : data.title}
</div>
</ButtonFrame>
@ -106,20 +106,20 @@ export const UndoStep = ({ update, state, step, Design, compact = false, index =
return (
<>
<p className="tw-text-sm tw-italic tw-font-medium tw-opacity-70 tw-text-right tw-p-0 tw-tw-m-0 tw--mb-2 tw-pr-2">
<p className="tw:text-sm tw:italic tw:font-medium tw:opacity-70 tw:text-right tw:p-0 tw:tw:m-0 tw:-mb-2 tw:pr-2">
<UndoStepTimeAgo step={step} />
</p>
<ButtonFrame onClick={() => update.restore(index, state._)}>
<div className="tw-flex tw-flex-row tw-items-center tw-justify-between tw-gap-2 tw-w-full tw-m-0 tw-p-0 tw--mt-2 tw-text-lg">
<span className="tw-flex tw-flex-row tw-gap-2 tw-items-center">
<div className="tw:flex tw:flex-row tw:items-center tw:justify-between tw:gap-2 tw:w-full tw:m-0 tw:p-0 tw:-mt-2 tw:text-lg">
<span className="tw:flex tw:flex-row tw:gap-2 tw:items-center">
{data.fieldIcon || null}
{data.title}
</span>
<span className="tw-opacity-70 tw-flex tw-flex-row tw-gap-1 tw-items-center tw-text-base">
<span className="tw:opacity-70 tw:flex tw:flex-row tw:gap-1 tw:items-center tw:text-base">
{data.icon || null} {data.menu}
</span>
</div>
<div className="tw-flex tw-flex-row tw-gap-1 tw-items-center tw-align-start tw-w-full">
<div className="tw:flex tw:flex-row tw:gap-1 tw:items-center tw:align-start tw:w-full">
{data.msg ? (
data.msg
) : (
@ -127,8 +127,8 @@ export const UndoStep = ({ update, state, step, Design, compact = false, index =
<span className="">
{Array.isArray(data.newVal) ? data.newVal.join(', ') : data.newVal}
</span>
<LeftIcon className="tw-w-4 tw-h-4 tw-text-secondary tw-shrink-0" stroke={4} />
<span className="tw-line-through tw-decoration-1 tw-opacity-70">
<LeftIcon className="tw:w-4 tw:h-4 tw:text-secondary tw:shrink-0" stroke={4} />
<span className="tw:line-through tw:decoration-1 tw:opacity-70">
{Array.isArray(data.oldVal) ? data.oldVal.join(', ') : data.oldVal}
</span>
</>

View file

@ -20,16 +20,16 @@ export const ViewPicker = ({ Design, update, state }) => {
*/
if (state._.missingMeasurements.length > 1)
return (
<div className="tw-text-center tw-mt-8 tw-mb-24 tw-px-4 tw-max-w-xl tw-mx-auto">
<div className="tw:text-center tw:mt-8 tw:mb-24 tw:px-4 tw:max-w-xl tw:mx-auto">
<H2>Choose a view</H2>
<div className="tw-flex tw-flex-col tw-mx-auto tw-justify-center tw-gap-2 tw-mt-4">
<div className="tw:flex tw:flex-col tw:mx-auto tw:justify-center tw:gap-2 tw:mt-4">
{config.measurementsFreeViews
.filter((view) => view !== 'picker')
.map((view) => (
<MainCard key={view} {...{ view, update, Design }} />
))}
<Popout note>
<div className="tw-text-left">
<div className="tw:text-left">
<H5>pe:measurementsFreeViewsOnly.t:</H5>
<p>pe:measurementsFreeViewsOnly.d</p>
</div>
@ -39,20 +39,20 @@ export const ViewPicker = ({ Design, update, state }) => {
)
return (
<div className="tw-text-center tw-mt-8 tw-mb-24 tw-px-4">
<div className="tw:text-center tw:mt-8 tw:mb-24 tw:px-4">
<H2>Choose an Editor View</H2>
<div className="tw-max-w-6xl tw-grid tw-grid-cols-1 lg:tw-grid-cols-2 tw-mx-auto tw-justify-center tw-gap-2 lg:tw-gap-4 tw-mt-4">
<div className="tw:max-w-6xl tw:grid tw:grid-cols-1 tw:lg:grid-cols-2 tw:mx-auto tw:justify-center tw:gap-2 tw:lg:gap-4 tw:mt-4">
{config.mainViews.map((view) => (
<MainCard key={view} {...{ view, update, Design }} />
))}
</div>
<div className="tw-max-w-6xl tw-grid tw-grid-cols-1 lg:tw-grid-cols-4 tw-mx-auto tw-justify-center tw-gap-2 lg:tw-gap-4 tw-mt-4">
<div className="tw:max-w-6xl tw:grid tw:grid-cols-1 tw:lg:grid-cols-4 tw:mx-auto tw:justify-center tw:gap-2 tw:lg:gap-4 tw:mt-4">
{config.extraViews.map((view) => (
<ExtraCard key={view} {...{ view, update }} />
))}
</div>
{showDev || state.ui.ux > 3 ? (
<div className="tw-max-w-6xl tw-grid tw-grid-cols-1 lg:tw-grid-cols-4 tw-mx-auto tw-justify-center tw-gap-2 lg:tw-gap-4 tw-mt-4">
<div className="tw:max-w-6xl tw:grid tw:grid-cols-1 tw:lg:grid-cols-4 tw:mx-auto tw:justify-center tw:gap-2 tw:lg:gap-4 tw:mt-4">
{config.devViews.map((view) => (
<ExtraCard key={view} {...{ view, update }} />
))}
@ -60,7 +60,7 @@ export const ViewPicker = ({ Design, update, state }) => {
) : null}
{state.ui.ux < 4 ? (
<button
className="tw-daisy-btn tw-daisy-btn-ghost tw-mt-2"
className="tw:daisy-btn tw:daisy-btn-ghost tw:mt-2"
onClick={() => setShowDev(!showDev)}
>
{showDev ? 'Hide' : 'Show'} Advanced Views
@ -75,19 +75,19 @@ const MainCard = ({ view, update, Design }) => {
return (
<button
className={`tw-border tw-shadow tw-p-4 tw-rounded-lg tw-w-full hover:tw-bg-secondary hover:tw-bg-opacity-20 tw-flex tw-flex-col`}
className={`tw:border tw:shadow tw:p-4 tw:rounded-lg tw:w-full tw:hover:bg-secondary/20 tw:flex tw:flex-col`}
title={viewLabels[view].t}
onClick={() => update.view(view)}
>
<H4>
<div
className={`tw-flex tw-flex-row tw-items-start tw-justify-between tw-p-0 tw-mb-2 tw-text-left`}
className={`tw:flex tw:flex-row tw:items-start tw:justify-between tw:p-0 tw:mb-2 tw:text-left`}
>
<span>{viewLabels[view].t}</span>
<Icon className="tw-w-10 tw-h-10" />
<Icon className="tw:w-10 tw:h-10" />
</div>
</H4>
<p className={`tw-text-left tw-text-lg tw-m-0 tw-p-0 tw-grow-2 tw-font-medium`}>
<p className={`tw:text-left tw:text-lg tw:m-0 tw:p-0 tw:grow-2 tw:font-medium`}>
{viewLabels[view].d}
</p>
</button>
@ -98,17 +98,17 @@ const ExtraCard = ({ view, update }) => {
const Icon = viewIcons[view]
return (
<button
className="tw-border tw-shadow tw-p-3 tw-rounded-lg tw-w-full hover:tw-bg-secondary hover:tw-bg-opacity-20 tw-flex tw-flex-col"
className="tw:border tw:shadow tw:p-3 tw:rounded-lg tw:w-full tw:hover:bg-secondary/20 tw:flex tw:flex-col"
title={viewLabels[view].t}
onClick={() => update.view(view)}
>
<H5>
<div className="tw-flex tw-flex-row tw-items-center tw-justify-between tw-p-0 tw-mb-1 tw-text-left">
<div className="tw:flex tw:flex-row tw:items-center tw:justify-between tw:p-0 tw:mb-1 tw:text-left">
<span>{viewLabels[view].t}</span>
<Icon className="tw-w-8 tw-h-8" />
<Icon className="tw:w-8 tw:h-8" />
</div>
</H5>
<p className="tw-text-left tw-m-0 tw-p-0 tw-grow-2">{viewLabels[view].d}</p>
<p className="tw:text-left tw:m-0 tw:p-0 tw:grow-2">{viewLabels[view].d}</p>
</button>
)
}

View file

@ -72,13 +72,13 @@ export const View = (props) => {
if (view === 'timing') return <TimingView {...props} />
if (view === 'picker') return <ViewPicker {...props} />
return <h1 className="tw-ext-center tw-my-12">No view component for view {props.view}</h1>
return <h1 className="tw:ext-center tw:my-12">No view component for view {props.view}</h1>
}
/*
* This returns a view-specific icon
*/
export const ViewIcon = ({ view, className = 'tw-w-6 tw-h-6' }) => {
export const ViewIcon = ({ view, className = 'tw:w-6 tw:h-6' }) => {
const Icon = viewIcons[view] || FixmeIcon
return <Icon className={className} />

View file

@ -62,7 +62,7 @@ export function menuCoreSettingsSaboolHandler({ toggleSa }) {
}
const CoreDocsLink = ({ item }) => (
<a href={`/docs/about/site/draft/#${item.toLowerCase()}`} className={`${linkClasses} tw-px-2`}>
<a href={`/docs/about/site/draft/#${item.toLowerCase()}`} className={`${linkClasses} tw:px-2`}>
Learn more
</a>
)

View file

@ -7,7 +7,7 @@ import { linkClasses } from '@freesewing/utils'
const DesignDocsLink = ({ design, item }) => (
<a
href={`/docs/designs/${design}/options/#${item.toLowerCase()}`}
className={`${linkClasses} tw-px-2`}
className={`${linkClasses} tw:px-2`}
target="_BLANK"
>
Learn more

View file

@ -10,7 +10,7 @@ import {
} from '@freesewing/react/components/Icon'
const UiDocsLink = ({ item }) => (
<a href={`/docs/about/site/draft/#${item.toLowerCase()}`} className={`${linkClasses} tw-px-2`}>
<a href={`/docs/about/site/draft/#${item.toLowerCase()}`} className={`${linkClasses} tw:px-2`}>
Learn more
</a>
)
@ -63,15 +63,15 @@ export function menuLayoutSettingsStructure(units) {
list: ['portrait', 'landscape'],
choiceTitles: {
portrait: (
<div className="tw-flex tw-flex-row tw-items-center tw-gap-4">
<PatternIcon className="tw-h-5 tw-w-5" />
<span className="tw-grow">Portrait (tall)</span>
<div className="tw:flex tw:flex-row tw:items-center tw:gap-4">
<PatternIcon className="tw:h-5 tw:w-5" />
<span className="tw:grow">Portrait (tall)</span>
</div>
),
landscape: (
<div className="tw-flex tw-flex-row tw-items-center tw-gap-4">
<PatternIcon className="tw-h-5 tw-w-5 tw--rotate-90" />
<span className="tw-grow">Landscape (wide)</span>
<div className="tw:flex tw:flex-row tw:items-center tw:gap-4">
<PatternIcon className="tw:h-5 tw:w-5 tw:-rotate-90" />
<span className="tw:grow">Landscape (wide)</span>
</div>
),
},

View file

@ -4,7 +4,7 @@ import { linkClasses } from '@freesewing/utils'
import { AsideIcon, RotateIcon, RocketIcon, UxIcon } from '@freesewing/react/components/Icon'
const UiDocsLink = ({ item }) => (
<a href={`/docs/about/site/draft/#${item.toLowerCase()}`} className={`${linkClasses} tw-px-2`}>
<a href={`/docs/about/site/draft/#${item.toLowerCase()}`} className={`${linkClasses} tw:px-2`}>
Learn more
</a>
)