@beautinique/frontend-components 1.0.7 → 1.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +180 -14
- package/dist/auth/AuthBottomInstructions.d.cts +42 -0
- package/dist/auth/AuthBottomInstructions.d.cts.map +1 -0
- package/dist/auth/AuthBottomInstructions.d.ts +42 -0
- package/dist/auth/AuthBottomInstructions.d.ts.map +1 -0
- package/dist/auth/index.cjs +76 -0
- package/dist/auth/index.cjs.map +1 -0
- package/dist/auth/index.d.cts +2 -0
- package/dist/auth/index.d.cts.map +1 -0
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +74 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/index.cjs +14 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/layout/ScrollToTop.d.cts +36 -0
- package/dist/layout/ScrollToTop.d.cts.map +1 -0
- package/dist/layout/ScrollToTop.d.ts +36 -0
- package/dist/layout/ScrollToTop.d.ts.map +1 -0
- package/dist/layout/index.cjs +33 -0
- package/dist/layout/index.cjs.map +1 -0
- package/dist/layout/index.d.cts +2 -0
- package/dist/layout/index.d.cts.map +1 -0
- package/dist/layout/index.d.ts +2 -0
- package/dist/layout/index.d.ts.map +1 -0
- package/dist/layout/index.js +31 -0
- package/dist/layout/index.js.map +1 -0
- package/dist/lib/content.d.cts +7 -0
- package/dist/lib/content.d.cts.map +1 -0
- package/dist/lib/content.d.ts +7 -0
- package/dist/lib/content.d.ts.map +1 -0
- package/dist/lib/countdown.d.cts +13 -0
- package/dist/lib/countdown.d.cts.map +1 -0
- package/dist/lib/countdown.d.ts +13 -0
- package/dist/lib/countdown.d.ts.map +1 -0
- package/dist/lib/stepper.d.cts +9 -0
- package/dist/lib/stepper.d.cts.map +1 -0
- package/dist/lib/stepper.d.ts +9 -0
- package/dist/lib/stepper.d.ts.map +1 -0
- package/dist/linear-gradient/LinearGradient.d.cts +13 -0
- package/dist/linear-gradient/LinearGradient.d.cts.map +1 -0
- package/dist/linear-gradient/LinearGradient.d.ts +13 -0
- package/dist/linear-gradient/LinearGradient.d.ts.map +1 -0
- package/dist/linear-gradient/index.cjs +25 -0
- package/dist/linear-gradient/index.cjs.map +1 -0
- package/dist/linear-gradient/index.d.cts +2 -0
- package/dist/linear-gradient/index.d.cts.map +1 -0
- package/dist/linear-gradient/index.d.ts +2 -0
- package/dist/linear-gradient/index.d.ts.map +1 -0
- package/dist/linear-gradient/index.js +23 -0
- package/dist/linear-gradient/index.js.map +1 -0
- package/dist/resend/Resend.d.cts +37 -0
- package/dist/resend/Resend.d.cts.map +1 -0
- package/dist/resend/Resend.d.ts +37 -0
- package/dist/resend/Resend.d.ts.map +1 -0
- package/dist/resend/index.cjs +138 -0
- package/dist/resend/index.cjs.map +1 -0
- package/dist/resend/index.d.cts +2 -0
- package/dist/resend/index.d.cts.map +1 -0
- package/dist/resend/index.d.ts +2 -0
- package/dist/resend/index.d.ts.map +1 -0
- package/dist/resend/index.js +136 -0
- package/dist/resend/index.js.map +1 -0
- package/dist/stepper/Stepper.d.cts +35 -0
- package/dist/stepper/Stepper.d.cts.map +1 -0
- package/dist/stepper/Stepper.d.ts +35 -0
- package/dist/stepper/Stepper.d.ts.map +1 -0
- package/dist/stepper/index.cjs +149 -0
- package/dist/stepper/index.cjs.map +1 -0
- package/dist/stepper/index.d.cts +2 -0
- package/dist/stepper/index.d.cts.map +1 -0
- package/dist/stepper/index.d.ts +2 -0
- package/dist/stepper/index.d.ts.map +1 -0
- package/dist/stepper/index.js +147 -0
- package/dist/stepper/index.js.map +1 -0
- package/dist/stepper/stepper-icons.d.cts +10 -0
- package/dist/stepper/stepper-icons.d.cts.map +1 -0
- package/dist/stepper/stepper-icons.d.ts +10 -0
- package/dist/stepper/stepper-icons.d.ts.map +1 -0
- package/dist/theme/Theme.d.cts +23 -0
- package/dist/theme/Theme.d.cts.map +1 -0
- package/dist/theme/Theme.d.ts +23 -0
- package/dist/theme/Theme.d.ts.map +1 -0
- package/dist/theme/index.cjs +76 -0
- package/dist/theme/index.cjs.map +1 -0
- package/dist/theme/index.d.cts +2 -0
- package/dist/theme/index.d.cts.map +1 -0
- package/dist/theme/index.d.ts +2 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +74 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/theme-icons.d.cts +21 -0
- package/dist/theme/theme-icons.d.cts.map +1 -0
- package/dist/theme/theme-icons.d.ts +21 -0
- package/dist/theme/theme-icons.d.ts.map +1 -0
- package/dist/ui/Badge.d.cts +12 -0
- package/dist/ui/Badge.d.cts.map +1 -0
- package/dist/ui/Badge.d.ts +12 -0
- package/dist/ui/Badge.d.ts.map +1 -0
- package/dist/ui/Divider.d.cts +12 -0
- package/dist/ui/Divider.d.cts.map +1 -0
- package/dist/ui/Divider.d.ts +12 -0
- package/dist/ui/Divider.d.ts.map +1 -0
- package/dist/ui/GradientText.d.cts +30 -0
- package/dist/ui/GradientText.d.cts.map +1 -0
- package/dist/ui/GradientText.d.ts +30 -0
- package/dist/ui/GradientText.d.ts.map +1 -0
- package/dist/ui/index.cjs +37 -3
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.d.cts +3 -0
- package/dist/ui/index.d.cts.map +1 -1
- package/dist/ui/index.d.ts +3 -0
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +35 -4
- package/dist/ui/index.js.map +1 -1
- package/package.json +42 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/content.ts","../../src/lib/stepper.ts","../../src/stepper/stepper-icons.ts","../../src/stepper/Stepper.tsx"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { ReactNode } from 'react';\n\n/**\n * Whether React would show something for `content`. `null`, `undefined`, booleans and an empty string\n * show nothing; `0` does show (the text \"0\"), which is why this is not a plain truthiness check.\n */\nexport const hasContent = (content: ReactNode) =>\n content !== null &&\n content !== undefined &&\n content !== false &&\n content !== true &&\n content !== '';\n","export type TStepState = 'completed' | 'active' | 'upcoming';\n\n/**\n * The step that is the current one: `activeStep` kept inside the steps. A number past the ends (or\n * with a fraction) is put on the nearest step, and `NaN` is the first, so a wrong value never makes\n * every step look completed or none look current.\n */\nexport const getCurrentStep = (activeStep: number, count: number) =>\n Number.isNaN(activeStep)\n ? 0\n : Math.min(Math.max(Math.trunc(activeStep), 0), Math.max(count - 1, 0));\n\nexport const getStepState = (index: number, currentStep: number): TStepState => {\n if (index < currentStep) return 'completed';\n\n return index === currentStep ? 'active' : 'upcoming';\n};\n","import { addCollection, type IconifyJSON } from '@iconify/react';\n\n/*\n * The tick of a completed step. Iconify downloads an icon from its API the first time it is shown,\n * which cannot work offline and leaves an empty circle until it arrives, so the icon is bundled here\n * and registered with Iconify (the same way as the toast icons, see `toast-icons.ts`).\n *\n * An icon a step asks for with `icon: 'solar:...'` is the app's and is downloaded as usual; add it to\n * the app with `addCollection` when it has to show without a network.\n *\n * The data is what `https://api.iconify.design/<prefix>.json?icons=<name>` answers.\n */\nconst STEPPER_ICON_SETS: IconifyJSON[] = [\n {\n prefix: 'solar',\n width: 24,\n height: 24,\n icons: {\n 'check-read-linear': {\n body: '<g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\"><path d=\"M4 12.9L7.14286 16.5L15 7.5\"/><path d=\"M20 7.5625L11.4283 16.5625L11 16\"/></g>',\n },\n },\n },\n];\n\nlet registered = false;\n\n/**\n * Registers the icons above with Iconify. `Stepper` calls it when it renders, not when this file is\n * imported: an app that never renders a stepper never runs it, and nothing depends on the bundler\n * keeping an import that is only there for its effect (see `toast-icons.ts`). Calling it again is\n * harmless.\n */\nexport const registerStepperIcons = () => {\n if (registered) return;\n\n for (const iconSet of STEPPER_ICON_SETS) addCollection(iconSet);\n registered = true;\n};\n\n/** Every icon name registered above, e.g. `solar:check-read-linear`. */\nexport const STEPPER_ICON_NAMES = STEPPER_ICON_SETS.flatMap(({ prefix, icons }) =>\n Object.keys(icons).map((name) => `${prefix}:${name}`),\n);\n","import { Icon } from '@iconify/react';\nimport type { ComponentProps, CSSProperties } from 'react';\n\nimport { hasContent } from '../lib/content.js';\nimport { getCurrentStep, getStepState, type TStepState } from '../lib/stepper.js';\nimport { registerStepperIcons } from './stepper-icons.js';\n\nexport interface IStepperStep {\n title: string;\n description?: string;\n /**\n * An Iconify name (`'solar:user-linear'`) shown in the circle while the step is not completed; the\n * step's number if left out. Iconify downloads it the first time it is shown and draws it in the\n * browser, not on a server: to have it without a network, bundle it in the app (`addCollection`).\n */\n icon?: string;\n /** Cannot be clicked. Only matters when `onStepClick` is given. */\n disabled?: boolean;\n}\n\nexport interface IStepper extends ComponentProps<'div'> {\n steps: readonly IStepperStep[];\n /** The index of the current step: the ones before it are completed, the ones after it are upcoming. */\n activeStep: number;\n /** Makes the steps buttons. It gets the index of the step that was clicked. */\n onStepClick?: (step: number) => void;\n /** Names the list of steps for assistive technology, e.g. `\"Checkout progress\"`. */\n label?: string;\n /**\n * What assistive technology reads before the title of a completed step, which otherwise only shows\n * a tick.\n * @default 'Completed'\n */\n completedLabel?: string;\n}\n\nconst ITEM_CSS =\n 'group relative flex min-w-0 items-start gap-3 text-left md:flex-col md:items-center md:gap-3 md:px-2';\n// No `outline-hidden`: in Tailwind v4 it sets `--tw-outline-style: none`, which the\n// `focus-visible:outline-2` below uses for its style, so the ring would never be drawn. A button only\n// shows the browser's own ring for the keyboard anyway (`:focus-visible`), never for a click.\nconst CLICKABLE_CSS =\n 'cursor-pointer rounded-lg focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-blue-crayola-c disabled:cursor-not-allowed disabled:opacity-50';\n\nconst CIRCLE_CSS =\n 'relative z-1 flex size-10 shrink-0 items-center justify-center rounded-full border text-sm font-semibold transition-all duration-300 motion-reduce:transition-none md:size-11';\n\n// `Record`s: a new state is a type error here until it has a look. Every state also looks different\n// in forced-colors mode (Windows high contrast), where backgrounds and shadows are not drawn.\nconst CIRCLE_STATE_CSS: Record<TStepState, string> = {\n completed:\n 'border-blue-crayola-c bg-accent-duo text-white shadow-[0_8px_24px_rgba(var(--blue-crayola-c-rgb),0.28)] forced-colors:border-[Highlight] forced-colors:bg-[Highlight] forced-colors:bg-none forced-colors:text-[HighlightText]',\n active:\n 'border-blue-crayola-c bg-primary-invert text-primary shadow-[0_0_0_5px_rgba(var(--blue-crayola-c-rgb),0.12)] forced-colors:border-[Highlight] forced-colors:border-4',\n upcoming:\n 'border-primary/20 bg-primary-invert text-primary/60 forced-colors:border-[GrayText] forced-colors:text-[GrayText]',\n};\n\nconst TITLE_STATE_CSS: Record<TStepState, string> = {\n completed: 'text-primary/80',\n active: 'text-primary',\n upcoming: 'text-primary/45 forced-colors:text-[GrayText]',\n};\n\nconst DESCRIPTION_STATE_CSS: Record<TStepState, string> = {\n completed: 'text-primary/35',\n active: 'text-secondary',\n upcoming: 'text-primary/35 forced-colors:text-[GrayText]',\n};\n\nconst CONNECTOR_BASE_CSS =\n 'absolute top-10 left-5 h-4 w-0.5 -translate-x-1/2 md:top-5 md:left-[calc(50%+1.375rem)] md:h-0.5 md:w-[calc(100%-2.75rem)] md:translate-x-0';\n\n/**\n * A row of steps with the current one marked, for a checkout, a sign-up or any other wizard. The\n * steps are an ordered list; the current one has `aria-current=\"step\"`. With `onStepClick` the steps\n * are buttons, and the content in `children` is shown under them.\n */\nexport const Stepper = ({\n steps,\n activeStep,\n onStepClick,\n label,\n completedLabel = 'Completed',\n className = '',\n children,\n ...divProps\n}: IStepper) => {\n registerStepperIcons();\n\n const currentStep = getCurrentStep(activeStep, steps.length);\n\n return (\n <div\n {...divProps}\n className={`flex w-full flex-col gap-6 p-4 shadow-sm sm:p-5 lg:p-6 ${className}`}\n >\n {steps.length > 0 && (\n <ol\n aria-label={label}\n style={{ '--steps-count': steps.length } as CSSProperties}\n className=\"m-0 flex list-none flex-col gap-4 p-0 md:grid md:grid-cols-[repeat(var(--steps-count),minmax(0,1fr))] md:gap-0\"\n >\n {steps.map((step, index) => {\n const state = getStepState(index, currentStep);\n const hasNextStep = index < steps.length - 1;\n\n const content = (\n <>\n {hasNextStep && (\n <span\n aria-hidden=\"true\"\n className={`${CONNECTOR_BASE_CSS} ${\n state === 'completed'\n ? 'bg-accent-duo forced-colors:bg-[Highlight] forced-colors:bg-none'\n : 'bg-primary/20 forced-colors:bg-[GrayText]'\n }`}\n />\n )}\n\n <span aria-hidden=\"true\" className={`${CIRCLE_CSS} ${CIRCLE_STATE_CSS[state]}`}>\n {state === 'completed' ? (\n <Icon icon=\"solar:check-read-linear\" className=\"size-5\" />\n ) : step.icon ? (\n <Icon icon={step.icon} className=\"size-5\" />\n ) : (\n index + 1\n )}\n </span>\n\n <span className=\"flex min-w-0 flex-1 flex-col gap-1 pt-0.5 md:items-center md:pt-0 md:text-center\">\n <span\n className={`line-clamp-1 text-sm font-semibold md:text-[13px] lg:text-sm ${TITLE_STATE_CSS[state]}`}\n >\n {state === 'completed' && (\n <span className=\"sr-only\">{`${completedLabel}: `}</span>\n )}\n {step.title}\n </span>\n {hasContent(step.description) && (\n <span\n className={`line-clamp-1 text-xs leading-4 md:line-clamp-2 ${DESCRIPTION_STATE_CSS[state]}`}\n >\n {step.description}\n </span>\n )}\n </span>\n </>\n );\n\n return (\n // The steps are a fixed order that is never sorted or filtered, and two can have the\n // same title: the place is what tells them apart.\n <li\n key={index}\n data-state={state}\n aria-current={state === 'active' ? 'step' : undefined}\n >\n {onStepClick ? (\n <button\n type=\"button\"\n disabled={step.disabled}\n onClick={() => {\n onStepClick(index);\n }}\n className={`${ITEM_CSS} ${CLICKABLE_CSS} w-full`}\n >\n {content}\n </button>\n ) : (\n <div className={`${ITEM_CSS} cursor-default`}>{content}</div>\n )}\n </li>\n );\n })}\n </ol>\n )}\n\n {hasContent(children) && <div className=\"border-primary/10 border-t pt-5\">{children}</div>}\n </div>\n );\n};\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registers the icons above with Iconify. `Stepper` calls it when it renders, not when this file is
|
|
3
|
+
* imported: an app that never renders a stepper never runs it, and nothing depends on the bundler
|
|
4
|
+
* keeping an import that is only there for its effect (see `toast-icons.ts`). Calling it again is
|
|
5
|
+
* harmless.
|
|
6
|
+
*/
|
|
7
|
+
export declare const registerStepperIcons: () => void;
|
|
8
|
+
/** Every icon name registered above, e.g. `solar:check-read-linear`. */
|
|
9
|
+
export declare const STEPPER_ICON_NAMES: string[];
|
|
10
|
+
//# sourceMappingURL=stepper-icons.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stepper-icons.d.cts","sourceRoot":"","sources":["../../src/stepper/stepper-icons.ts"],"names":[],"mappings":"AA2BA;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,YAKhC,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,kBAAkB,UAE9B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registers the icons above with Iconify. `Stepper` calls it when it renders, not when this file is
|
|
3
|
+
* imported: an app that never renders a stepper never runs it, and nothing depends on the bundler
|
|
4
|
+
* keeping an import that is only there for its effect (see `toast-icons.ts`). Calling it again is
|
|
5
|
+
* harmless.
|
|
6
|
+
*/
|
|
7
|
+
export declare const registerStepperIcons: () => void;
|
|
8
|
+
/** Every icon name registered above, e.g. `solar:check-read-linear`. */
|
|
9
|
+
export declare const STEPPER_ICON_NAMES: string[];
|
|
10
|
+
//# sourceMappingURL=stepper-icons.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stepper-icons.d.ts","sourceRoot":"","sources":["../../src/stepper/stepper-icons.ts"],"names":[],"mappings":"AA2BA;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,YAKhC,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,kBAAkB,UAE9B,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { TThemeStoreHook } from '@beautinique/frontend-stores';
|
|
2
|
+
import type { ComponentProps } from 'react';
|
|
3
|
+
export interface ITheme extends Omit<ComponentProps<'button'>, 'children' | 'onClick' | 'type' | 'aria-label'> {
|
|
4
|
+
/** The theme store of the app: what `createThemeStore()` of `@beautinique/frontend-stores` gave it. */
|
|
5
|
+
store: TThemeStoreHook;
|
|
6
|
+
/** What the button says to assistive technology, for the theme it would switch to. */
|
|
7
|
+
labels?: {
|
|
8
|
+
/** @default 'Switch to light theme' */
|
|
9
|
+
toLight?: string;
|
|
10
|
+
/** @default 'Switch to dark theme' */
|
|
11
|
+
toDark?: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A button that switches between the dark and the light theme. It shows the theme it would switch
|
|
16
|
+
* to: a sun while the theme is dark, a moon while it is light. It only changes the store; putting the
|
|
17
|
+
* theme on the page (a class on `<html>`) is the app's.
|
|
18
|
+
*
|
|
19
|
+
* The icons move; for a person who asked their system for less motion (`prefers-reduced-motion`)
|
|
20
|
+
* the button shows still ones instead.
|
|
21
|
+
*/
|
|
22
|
+
export declare const Theme: ({ store: useThemeStore, labels, className, ...buttonProps }: ITheme) => import("react").JSX.Element;
|
|
23
|
+
//# sourceMappingURL=Theme.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Theme.d.cts","sourceRoot":"","sources":["../../src/theme/Theme.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAI5C,MAAM,WAAW,MAAO,SAAQ,IAAI,CAClC,cAAc,CAAC,QAAQ,CAAC,EACxB,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,YAAY,CAC/C;IACC,uGAAuG;IACvG,KAAK,EAAE,eAAe,CAAC;IACvB,sFAAsF;IACtF,MAAM,CAAC,EAAE;QACP,uCAAuC;QACvC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,sCAAsC;QACtC,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAWD;;;;;;;GAOG;AACH,eAAO,MAAM,KAAK,GAAI,6DAAkE,MAAM,gCAuB7F,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { TThemeStoreHook } from '@beautinique/frontend-stores';
|
|
2
|
+
import type { ComponentProps } from 'react';
|
|
3
|
+
export interface ITheme extends Omit<ComponentProps<'button'>, 'children' | 'onClick' | 'type' | 'aria-label'> {
|
|
4
|
+
/** The theme store of the app: what `createThemeStore()` of `@beautinique/frontend-stores` gave it. */
|
|
5
|
+
store: TThemeStoreHook;
|
|
6
|
+
/** What the button says to assistive technology, for the theme it would switch to. */
|
|
7
|
+
labels?: {
|
|
8
|
+
/** @default 'Switch to light theme' */
|
|
9
|
+
toLight?: string;
|
|
10
|
+
/** @default 'Switch to dark theme' */
|
|
11
|
+
toDark?: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* A button that switches between the dark and the light theme. It shows the theme it would switch
|
|
16
|
+
* to: a sun while the theme is dark, a moon while it is light. It only changes the store; putting the
|
|
17
|
+
* theme on the page (a class on `<html>`) is the app's.
|
|
18
|
+
*
|
|
19
|
+
* The icons move; for a person who asked their system for less motion (`prefers-reduced-motion`)
|
|
20
|
+
* the button shows still ones instead.
|
|
21
|
+
*/
|
|
22
|
+
export declare const Theme: ({ store: useThemeStore, labels, className, ...buttonProps }: ITheme) => import("react").JSX.Element;
|
|
23
|
+
//# sourceMappingURL=Theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Theme.d.ts","sourceRoot":"","sources":["../../src/theme/Theme.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAI5C,MAAM,WAAW,MAAO,SAAQ,IAAI,CAClC,cAAc,CAAC,QAAQ,CAAC,EACxB,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,YAAY,CAC/C;IACC,uGAAuG;IACvG,KAAK,EAAE,eAAe,CAAC;IACvB,sFAAsF;IACtF,MAAM,CAAC,EAAE;QACP,uCAAuC;QACvC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,sCAAsC;QACtC,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAWD;;;;;;;GAOG;AACH,eAAO,MAAM,KAAK,GAAI,6DAAkE,MAAM,gCAuB7F,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('@iconify/react');
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
|
|
6
|
+
var __defProp = Object.defineProperty;
|
|
7
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
8
|
+
var THEME_ICON_SETS = [
|
|
9
|
+
{
|
|
10
|
+
prefix: "line-md",
|
|
11
|
+
width: 24,
|
|
12
|
+
height: 24,
|
|
13
|
+
icons: {
|
|
14
|
+
"sunny-loop": {
|
|
15
|
+
body: '<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path stroke-dasharray="34" d="M12 7c2.76 0 5 2.24 5 5c0 2.76 -2.24 5 -5 5c-2.76 0 -5 -2.24 -5 -5c0 -2.76 2.24 -5 5 -5Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.4s" values="34;0"/></path><path d="M12 21v1M21 12h1M12 3v-1M3 12h-1" opacity="0"><animateTransform attributeName="transform" dur="30s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/><set fill="freeze" attributeName="opacity" begin="0.5s" to="1"/><animate fill="freeze" attributeName="d" begin="0.5s" dur="0.2s" values="M12 19v1M19 12h1M12 5v-1M5 12h-1;M12 21v1M21 12h1M12 3v-1M3 12h-1"/></path><path d="M18.5 18.5l0.5 0.5M18.5 5.5l0.5 -0.5M5.5 5.5l-0.5 -0.5M5.5 18.5l-0.5 0.5" opacity="0"><animateTransform attributeName="transform" dur="30s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/><set fill="freeze" attributeName="opacity" begin="0.7s" to="1"/><animate fill="freeze" attributeName="d" begin="0.7s" dur="0.2s" values="M17 17l0.5 0.5M17 7l0.5 -0.5M7 7l-0.5 -0.5M7 17l-0.5 0.5;M18.5 18.5l0.5 0.5M18.5 5.5l0.5 -0.5M5.5 5.5l-0.5 -0.5M5.5 18.5l-0.5 0.5"/></path></g>'
|
|
16
|
+
},
|
|
17
|
+
"moon-loop": {
|
|
18
|
+
body: '<path fill="none" stroke="currentColor" stroke-dasharray="56" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 6c0 6.08 4.92 11 11 11c0.53 0 1.05 -0.04 1.56 -0.11c-1.61 2.47 -4.39 4.11 -7.56 4.11c-4.97 0 -9 -4.03 -9 -9c0 -3.17 1.64 -5.95 4.11 -7.56c-0.07 0.51 -0.11 1.03 -0.11 1.56Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.6s" values="56;0"/></path><g fill="currentColor"><path d="M15.22 6.03l2.53 -1.94l-3.19 -0.09l-1.06 -3l-1.06 3l-3.19 0.09l2.53 1.94l-0.91 3.06l2.63 -1.81l2.63 1.81l-0.91 -3.06Z" opacity="0"><animate attributeName="opacity" begin="0.7s" dur="6s" keyTimes="0;0.1;0.4;0.5;1" repeatCount="indefinite" values="0;1;1;0;0"/></path><path d="M19.61 12.25l1.64 -1.25l-2.06 -0.05l-0.69 -1.95l-0.69 1.95l-2.06 0.05l1.64 1.25l-0.59 1.98l1.7 -1.17l1.7 1.17l-0.59 -1.98Z" opacity="0"><animate attributeName="opacity" begin="0.7s" dur="6s" keyTimes="0;0.2;0.3;0.6;0.7;1" repeatCount="indefinite" values="0;0;1;1;0;0"/></path><path d="M13.61 5.25l1.64 -1.25l-2.06 -0.05l-0.69 -1.95l-0.69 1.95l-2.06 0.05l1.64 1.25l-0.59 1.98l1.7 -1.17l1.7 1.17Z" opacity="0"><animate attributeName="opacity" begin="3.7s" dur="6s" keyTimes="0;0.1;0.4;0.5;1" repeatCount="indefinite" values="0;1;1;0;0"/></path><path d="M20.83 9.73l1.88 -1.44l-2.37 -0.07l-0.79 -2.22l-0.79 2.23l-2.37 0.07l1.88 1.44l-0.68 2.27l1.95 -1.34l1.95 1.34Z" opacity="0"><animate attributeName="opacity" begin="3.7s" dur="6s" keyTimes="0;0.2;0.3;0.6;0.7;1" repeatCount="indefinite" values="0;0;1;1;0;0"/></path></g>'
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
prefix: "solar",
|
|
24
|
+
width: 24,
|
|
25
|
+
height: 24,
|
|
26
|
+
icons: {
|
|
27
|
+
"sun-2-linear": {
|
|
28
|
+
body: '<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="1.5"><circle cx="12" cy="12" r="5"/><path d="M12 2V4"/><path d="M12 20V22"/><path d="M4 12L2 12"/><path d="M22 12L20 12"/><path d="M19.7778 4.22266L17.5558 6.25424"/><path d="M4.22217 4.22266L6.44418 6.25424"/><path d="M6.44434 17.5557L4.22211 19.7779"/><path d="M19.7778 19.7773L17.5558 17.5551"/></g>'
|
|
29
|
+
},
|
|
30
|
+
"moon-linear": {
|
|
31
|
+
body: '<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 22C17.5228 22 22 17.5228 22 12C22 11.5373 21.3065 11.4608 21.0672 11.8568C19.9289 13.7406 17.8615 15 15.5 15C11.9101 15 9 12.0899 9 8.5C9 6.13845 10.2594 4.07105 12.1432 2.93276C12.5392 2.69347 12.4627 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z"/>'
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
];
|
|
36
|
+
var THEME_ICONS = {
|
|
37
|
+
dark: { moving: "line-md:sunny-loop", still: "solar:sun-2-linear" },
|
|
38
|
+
light: { moving: "line-md:moon-loop", still: "solar:moon-linear" }
|
|
39
|
+
};
|
|
40
|
+
var registered = false;
|
|
41
|
+
var registerThemeIcons = /* @__PURE__ */ __name(() => {
|
|
42
|
+
if (registered) return;
|
|
43
|
+
for (const iconSet of THEME_ICON_SETS) react.addCollection(iconSet);
|
|
44
|
+
registered = true;
|
|
45
|
+
}, "registerThemeIcons");
|
|
46
|
+
THEME_ICON_SETS.flatMap(
|
|
47
|
+
({ prefix, icons }) => Object.keys(icons).map((name) => `${prefix}:${name}`)
|
|
48
|
+
);
|
|
49
|
+
var BUTTON_CSS = "relative size-5 cursor-pointer rounded-full after:absolute after:-inset-1 after:content-[''] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-crayola-c md:size-6";
|
|
50
|
+
var ICON_CSS = "text-tertiary hover:text-secondary size-full [&_path]:stroke-[1.5]";
|
|
51
|
+
var Theme = /* @__PURE__ */ __name(({ store: useThemeStore, labels, className = "", ...buttonProps }) => {
|
|
52
|
+
registerThemeIcons();
|
|
53
|
+
const theme = useThemeStore((state) => state.theme);
|
|
54
|
+
const toggleTheme = useThemeStore((state) => state.toggleTheme);
|
|
55
|
+
const isDark = theme === "dark";
|
|
56
|
+
const icons = THEME_ICONS[isDark ? "dark" : "light"];
|
|
57
|
+
const { toLight = "Switch to light theme", toDark = "Switch to dark theme" } = labels ?? {};
|
|
58
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
59
|
+
"button",
|
|
60
|
+
{
|
|
61
|
+
...buttonProps,
|
|
62
|
+
type: "button",
|
|
63
|
+
onClick: toggleTheme,
|
|
64
|
+
"aria-label": isDark ? toLight : toDark,
|
|
65
|
+
className: `${BUTTON_CSS} ${className}`,
|
|
66
|
+
children: [
|
|
67
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.Icon, { icon: icons.moving, className: `${ICON_CSS} motion-reduce:hidden` }),
|
|
68
|
+
/* @__PURE__ */ jsxRuntime.jsx(react.Icon, { icon: icons.still, className: `${ICON_CSS} hidden motion-reduce:block` })
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
}, "Theme");
|
|
73
|
+
|
|
74
|
+
exports.Theme = Theme;
|
|
75
|
+
//# sourceMappingURL=index.cjs.map
|
|
76
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/theme/theme-icons.ts","../../src/theme/Theme.tsx"],"names":["addCollection","jsxs","jsx","Icon"],"mappings":";;;;;;;AAYA,IAAM,eAAA,GAAiC;AAAA,EACrC;AAAA,IACE,MAAA,EAAQ,SAAA;AAAA,IACR,KAAA,EAAO,EAAA;AAAA,IACP,MAAA,EAAQ,EAAA;AAAA,IACR,KAAA,EAAO;AAAA,MACL,YAAA,EAAc;AAAA,QACZ,IAAA,EAAM;AAAA,OACR;AAAA,MACA,WAAA,EAAa;AAAA,QACX,IAAA,EAAM;AAAA;AACR;AACF,GACF;AAAA,EACA;AAAA,IACE,MAAA,EAAQ,OAAA;AAAA,IACR,KAAA,EAAO,EAAA;AAAA,IACP,MAAA,EAAQ,EAAA;AAAA,IACR,KAAA,EAAO;AAAA,MACL,cAAA,EAAgB;AAAA,QACd,IAAA,EAAM;AAAA,OACR;AAAA,MACA,aAAA,EAAe;AAAA,QACb,IAAA,EAAM;AAAA;AACR;AACF;AAEJ,CAAA;AAGO,IAAM,WAAA,GAAc;AAAA,EACzB,IAAA,EAAM,EAAE,MAAA,EAAQ,oBAAA,EAAsB,OAAO,oBAAA,EAAqB;AAAA,EAClE,KAAA,EAAO,EAAE,MAAA,EAAQ,mBAAA,EAAqB,OAAO,mBAAA;AAC/C,CAAA;AAEA,IAAI,UAAA,GAAa,KAAA;AAQV,IAAM,qCAAqB,MAAA,CAAA,MAAM;AACtC,EAAA,IAAI,UAAA,EAAY;AAEhB,EAAA,KAAA,MAAW,OAAA,IAAW,eAAA,EAAiBA,mBAAA,CAAc,OAAO,CAAA;AAC5D,EAAA,UAAA,GAAa,IAAA;AACf,CAAA,EALkC,oBAAA,CAAA;AAQF,eAAA,CAAgB,OAAA;AAAA,EAAQ,CAAC,EAAE,MAAA,EAAQ,KAAA,EAAM,KACvE,OAAO,IAAA,CAAK,KAAK,CAAA,CAAE,GAAA,CAAI,CAAC,IAAA,KAAS,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE;AACtD;ACvCA,IAAM,UAAA,GACJ,oMAAA;AACF,IAAM,QAAA,GAAW,oEAAA;AAUV,IAAM,KAAA,mBAAQ,MAAA,CAAA,CAAC,EAAE,KAAA,EAAO,aAAA,EAAe,QAAQ,SAAA,GAAY,EAAA,EAAI,GAAG,WAAA,EAAY,KAAc;AACjG,EAAA,kBAAA,EAAmB;AAEnB,EAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,CAAC,KAAA,KAAU,MAAM,KAAK,CAAA;AAClD,EAAA,MAAM,WAAA,GAAc,aAAA,CAAc,CAAC,KAAA,KAAU,MAAM,WAAW,CAAA;AAE9D,EAAA,MAAM,SAAS,KAAA,KAAU,MAAA;AACzB,EAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,MAAA,GAAS,MAAA,GAAS,OAAO,CAAA;AACnD,EAAA,MAAM,EAAE,OAAA,GAAU,uBAAA,EAAyB,SAAS,sBAAA,EAAuB,GAAI,UAAU,EAAC;AAE1F,EAAA,uBACEC,eAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACE,GAAG,WAAA;AAAA,MACJ,IAAA,EAAK,QAAA;AAAA,MACL,OAAA,EAAS,WAAA;AAAA,MACT,YAAA,EAAY,SAAS,OAAA,GAAU,MAAA;AAAA,MAC/B,SAAA,EAAW,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA;AAAA,MAGrC,QAAA,EAAA;AAAA,wBAAAC,cAAA,CAACC,cAAK,IAAA,EAAM,KAAA,CAAM,QAAQ,SAAA,EAAW,CAAA,EAAG,QAAQ,CAAA,qBAAA,CAAA,EAAyB,CAAA;AAAA,wBACzED,cAAA,CAACC,cAAK,IAAA,EAAM,KAAA,CAAM,OAAO,SAAA,EAAW,CAAA,EAAG,QAAQ,CAAA,2BAAA,CAAA,EAA+B;AAAA;AAAA;AAAA,GAChF;AAEJ,CAAA,EAvBqB,OAAA","file":"index.cjs","sourcesContent":["import { addCollection, type IconifyJSON } from '@iconify/react';\n\n/*\n * The icons of the theme button. Iconify downloads an icon from its API the first time it is shown,\n * which cannot work offline and leaves the button empty until it arrives, so they are bundled here and\n * registered with Iconify (the same way as the toast icons, see `toast-icons.ts`).\n *\n * For each theme there are two: one that moves (`line-md`, drawn with SMIL and never stops) and a\n * still one (`solar`) for a person who asked for less motion.\n *\n * The data is what `https://api.iconify.design/<prefix>.json?icons=<name>` answers.\n */\nconst THEME_ICON_SETS: IconifyJSON[] = [\n {\n prefix: 'line-md',\n width: 24,\n height: 24,\n icons: {\n 'sunny-loop': {\n body: '<g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path stroke-dasharray=\"34\" d=\"M12 7c2.76 0 5 2.24 5 5c0 2.76 -2.24 5 -5 5c-2.76 0 -5 -2.24 -5 -5c0 -2.76 2.24 -5 5 -5Z\"><animate fill=\"freeze\" attributeName=\"stroke-dashoffset\" dur=\"0.4s\" values=\"34;0\"/></path><path d=\"M12 21v1M21 12h1M12 3v-1M3 12h-1\" opacity=\"0\"><animateTransform attributeName=\"transform\" dur=\"30s\" repeatCount=\"indefinite\" type=\"rotate\" values=\"0 12 12;360 12 12\"/><set fill=\"freeze\" attributeName=\"opacity\" begin=\"0.5s\" to=\"1\"/><animate fill=\"freeze\" attributeName=\"d\" begin=\"0.5s\" dur=\"0.2s\" values=\"M12 19v1M19 12h1M12 5v-1M5 12h-1;M12 21v1M21 12h1M12 3v-1M3 12h-1\"/></path><path d=\"M18.5 18.5l0.5 0.5M18.5 5.5l0.5 -0.5M5.5 5.5l-0.5 -0.5M5.5 18.5l-0.5 0.5\" opacity=\"0\"><animateTransform attributeName=\"transform\" dur=\"30s\" repeatCount=\"indefinite\" type=\"rotate\" values=\"0 12 12;360 12 12\"/><set fill=\"freeze\" attributeName=\"opacity\" begin=\"0.7s\" to=\"1\"/><animate fill=\"freeze\" attributeName=\"d\" begin=\"0.7s\" dur=\"0.2s\" values=\"M17 17l0.5 0.5M17 7l0.5 -0.5M7 7l-0.5 -0.5M7 17l-0.5 0.5;M18.5 18.5l0.5 0.5M18.5 5.5l0.5 -0.5M5.5 5.5l-0.5 -0.5M5.5 18.5l-0.5 0.5\"/></path></g>',\n },\n 'moon-loop': {\n body: '<path fill=\"none\" stroke=\"currentColor\" stroke-dasharray=\"56\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 6c0 6.08 4.92 11 11 11c0.53 0 1.05 -0.04 1.56 -0.11c-1.61 2.47 -4.39 4.11 -7.56 4.11c-4.97 0 -9 -4.03 -9 -9c0 -3.17 1.64 -5.95 4.11 -7.56c-0.07 0.51 -0.11 1.03 -0.11 1.56Z\"><animate fill=\"freeze\" attributeName=\"stroke-dashoffset\" dur=\"0.6s\" values=\"56;0\"/></path><g fill=\"currentColor\"><path d=\"M15.22 6.03l2.53 -1.94l-3.19 -0.09l-1.06 -3l-1.06 3l-3.19 0.09l2.53 1.94l-0.91 3.06l2.63 -1.81l2.63 1.81l-0.91 -3.06Z\" opacity=\"0\"><animate attributeName=\"opacity\" begin=\"0.7s\" dur=\"6s\" keyTimes=\"0;0.1;0.4;0.5;1\" repeatCount=\"indefinite\" values=\"0;1;1;0;0\"/></path><path d=\"M19.61 12.25l1.64 -1.25l-2.06 -0.05l-0.69 -1.95l-0.69 1.95l-2.06 0.05l1.64 1.25l-0.59 1.98l1.7 -1.17l1.7 1.17l-0.59 -1.98Z\" opacity=\"0\"><animate attributeName=\"opacity\" begin=\"0.7s\" dur=\"6s\" keyTimes=\"0;0.2;0.3;0.6;0.7;1\" repeatCount=\"indefinite\" values=\"0;0;1;1;0;0\"/></path><path d=\"M13.61 5.25l1.64 -1.25l-2.06 -0.05l-0.69 -1.95l-0.69 1.95l-2.06 0.05l1.64 1.25l-0.59 1.98l1.7 -1.17l1.7 1.17Z\" opacity=\"0\"><animate attributeName=\"opacity\" begin=\"3.7s\" dur=\"6s\" keyTimes=\"0;0.1;0.4;0.5;1\" repeatCount=\"indefinite\" values=\"0;1;1;0;0\"/></path><path d=\"M20.83 9.73l1.88 -1.44l-2.37 -0.07l-0.79 -2.22l-0.79 2.23l-2.37 0.07l1.88 1.44l-0.68 2.27l1.95 -1.34l1.95 1.34Z\" opacity=\"0\"><animate attributeName=\"opacity\" begin=\"3.7s\" dur=\"6s\" keyTimes=\"0;0.2;0.3;0.6;0.7;1\" repeatCount=\"indefinite\" values=\"0;0;1;1;0;0\"/></path></g>',\n },\n },\n },\n {\n prefix: 'solar',\n width: 24,\n height: 24,\n icons: {\n 'sun-2-linear': {\n body: '<g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"1.5\"><circle cx=\"12\" cy=\"12\" r=\"5\"/><path d=\"M12 2V4\"/><path d=\"M12 20V22\"/><path d=\"M4 12L2 12\"/><path d=\"M22 12L20 12\"/><path d=\"M19.7778 4.22266L17.5558 6.25424\"/><path d=\"M4.22217 4.22266L6.44418 6.25424\"/><path d=\"M6.44434 17.5557L4.22211 19.7779\"/><path d=\"M19.7778 19.7773L17.5558 17.5551\"/></g>',\n },\n 'moon-linear': {\n body: '<path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M12 22C17.5228 22 22 17.5228 22 12C22 11.5373 21.3065 11.4608 21.0672 11.8568C19.9289 13.7406 17.8615 15 15.5 15C11.9101 15 9 12.0899 9 8.5C9 6.13845 10.2594 4.07105 12.1432 2.93276C12.5392 2.69347 12.4627 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z\"/>',\n },\n },\n },\n];\n\n/** What the button shows while the theme is dark (a sun: it would switch to light) and light (a moon). */\nexport const THEME_ICONS = {\n dark: { moving: 'line-md:sunny-loop', still: 'solar:sun-2-linear' },\n light: { moving: 'line-md:moon-loop', still: 'solar:moon-linear' },\n} as const;\n\nlet registered = false;\n\n/**\n * Registers the icons above with Iconify. `Theme` calls it when it renders, not when this file is\n * imported: an app that never renders the button never runs it, and nothing depends on the bundler\n * keeping an import that is only there for its effect (see `toast-icons.ts`). Calling it again is\n * harmless.\n */\nexport const registerThemeIcons = () => {\n if (registered) return;\n\n for (const iconSet of THEME_ICON_SETS) addCollection(iconSet);\n registered = true;\n};\n\n/** Every icon name registered above, e.g. `line-md:sunny-loop`. */\nexport const THEME_ICON_NAMES = THEME_ICON_SETS.flatMap(({ prefix, icons }) =>\n Object.keys(icons).map((name) => `${prefix}:${name}`),\n);\n","import type { TThemeStoreHook } from '@beautinique/frontend-stores';\nimport { Icon } from '@iconify/react';\nimport type { ComponentProps } from 'react';\n\nimport { registerThemeIcons, THEME_ICONS } from './theme-icons.js';\n\nexport interface ITheme extends Omit<\n ComponentProps<'button'>,\n 'children' | 'onClick' | 'type' | 'aria-label'\n> {\n /** The theme store of the app: what `createThemeStore()` of `@beautinique/frontend-stores` gave it. */\n store: TThemeStoreHook;\n /** What the button says to assistive technology, for the theme it would switch to. */\n labels?: {\n /** @default 'Switch to light theme' */\n toLight?: string;\n /** @default 'Switch to dark theme' */\n toDark?: string;\n };\n}\n\n// The hit area is bigger than the icon (the icon is 20px on a phone): the `after` box is a part of the\n// button, so a thumb that lands next to the icon still presses it, and nothing around it moves.\n// No `outline-hidden`: in Tailwind v4 it sets `--tw-outline-style: none`, which the\n// `focus-visible:outline-2` uses for its style, so the ring would never be drawn. A button only shows\n// the browser's own ring for the keyboard anyway (`:focus-visible`), never for a click.\nconst BUTTON_CSS =\n \"relative size-5 cursor-pointer rounded-full after:absolute after:-inset-1 after:content-[''] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-crayola-c md:size-6\";\nconst ICON_CSS = 'text-tertiary hover:text-secondary size-full [&_path]:stroke-[1.5]';\n\n/**\n * A button that switches between the dark and the light theme. It shows the theme it would switch\n * to: a sun while the theme is dark, a moon while it is light. It only changes the store; putting the\n * theme on the page (a class on `<html>`) is the app's.\n *\n * The icons move; for a person who asked their system for less motion (`prefers-reduced-motion`)\n * the button shows still ones instead.\n */\nexport const Theme = ({ store: useThemeStore, labels, className = '', ...buttonProps }: ITheme) => {\n registerThemeIcons();\n\n const theme = useThemeStore((state) => state.theme);\n const toggleTheme = useThemeStore((state) => state.toggleTheme);\n\n const isDark = theme === 'dark';\n const icons = THEME_ICONS[isDark ? 'dark' : 'light'];\n const { toLight = 'Switch to light theme', toDark = 'Switch to dark theme' } = labels ?? {};\n\n return (\n <button\n {...buttonProps}\n type=\"button\"\n onClick={toggleTheme}\n aria-label={isDark ? toLight : toDark}\n className={`${BUTTON_CSS} ${className}`}\n >\n {/* Both are in the page and css picks one: no script has to ask the system about motion. */}\n <Icon icon={icons.moving} className={`${ICON_CSS} motion-reduce:hidden`} />\n <Icon icon={icons.still} className={`${ICON_CSS} hidden motion-reduce:block`} />\n </button>\n );\n};\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../src/theme/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/theme/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Icon, addCollection } from '@iconify/react';
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
|
+
var THEME_ICON_SETS = [
|
|
7
|
+
{
|
|
8
|
+
prefix: "line-md",
|
|
9
|
+
width: 24,
|
|
10
|
+
height: 24,
|
|
11
|
+
icons: {
|
|
12
|
+
"sunny-loop": {
|
|
13
|
+
body: '<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path stroke-dasharray="34" d="M12 7c2.76 0 5 2.24 5 5c0 2.76 -2.24 5 -5 5c-2.76 0 -5 -2.24 -5 -5c0 -2.76 2.24 -5 5 -5Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.4s" values="34;0"/></path><path d="M12 21v1M21 12h1M12 3v-1M3 12h-1" opacity="0"><animateTransform attributeName="transform" dur="30s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/><set fill="freeze" attributeName="opacity" begin="0.5s" to="1"/><animate fill="freeze" attributeName="d" begin="0.5s" dur="0.2s" values="M12 19v1M19 12h1M12 5v-1M5 12h-1;M12 21v1M21 12h1M12 3v-1M3 12h-1"/></path><path d="M18.5 18.5l0.5 0.5M18.5 5.5l0.5 -0.5M5.5 5.5l-0.5 -0.5M5.5 18.5l-0.5 0.5" opacity="0"><animateTransform attributeName="transform" dur="30s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/><set fill="freeze" attributeName="opacity" begin="0.7s" to="1"/><animate fill="freeze" attributeName="d" begin="0.7s" dur="0.2s" values="M17 17l0.5 0.5M17 7l0.5 -0.5M7 7l-0.5 -0.5M7 17l-0.5 0.5;M18.5 18.5l0.5 0.5M18.5 5.5l0.5 -0.5M5.5 5.5l-0.5 -0.5M5.5 18.5l-0.5 0.5"/></path></g>'
|
|
14
|
+
},
|
|
15
|
+
"moon-loop": {
|
|
16
|
+
body: '<path fill="none" stroke="currentColor" stroke-dasharray="56" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 6c0 6.08 4.92 11 11 11c0.53 0 1.05 -0.04 1.56 -0.11c-1.61 2.47 -4.39 4.11 -7.56 4.11c-4.97 0 -9 -4.03 -9 -9c0 -3.17 1.64 -5.95 4.11 -7.56c-0.07 0.51 -0.11 1.03 -0.11 1.56Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.6s" values="56;0"/></path><g fill="currentColor"><path d="M15.22 6.03l2.53 -1.94l-3.19 -0.09l-1.06 -3l-1.06 3l-3.19 0.09l2.53 1.94l-0.91 3.06l2.63 -1.81l2.63 1.81l-0.91 -3.06Z" opacity="0"><animate attributeName="opacity" begin="0.7s" dur="6s" keyTimes="0;0.1;0.4;0.5;1" repeatCount="indefinite" values="0;1;1;0;0"/></path><path d="M19.61 12.25l1.64 -1.25l-2.06 -0.05l-0.69 -1.95l-0.69 1.95l-2.06 0.05l1.64 1.25l-0.59 1.98l1.7 -1.17l1.7 1.17l-0.59 -1.98Z" opacity="0"><animate attributeName="opacity" begin="0.7s" dur="6s" keyTimes="0;0.2;0.3;0.6;0.7;1" repeatCount="indefinite" values="0;0;1;1;0;0"/></path><path d="M13.61 5.25l1.64 -1.25l-2.06 -0.05l-0.69 -1.95l-0.69 1.95l-2.06 0.05l1.64 1.25l-0.59 1.98l1.7 -1.17l1.7 1.17Z" opacity="0"><animate attributeName="opacity" begin="3.7s" dur="6s" keyTimes="0;0.1;0.4;0.5;1" repeatCount="indefinite" values="0;1;1;0;0"/></path><path d="M20.83 9.73l1.88 -1.44l-2.37 -0.07l-0.79 -2.22l-0.79 2.23l-2.37 0.07l1.88 1.44l-0.68 2.27l1.95 -1.34l1.95 1.34Z" opacity="0"><animate attributeName="opacity" begin="3.7s" dur="6s" keyTimes="0;0.2;0.3;0.6;0.7;1" repeatCount="indefinite" values="0;0;1;1;0;0"/></path></g>'
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
prefix: "solar",
|
|
22
|
+
width: 24,
|
|
23
|
+
height: 24,
|
|
24
|
+
icons: {
|
|
25
|
+
"sun-2-linear": {
|
|
26
|
+
body: '<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="1.5"><circle cx="12" cy="12" r="5"/><path d="M12 2V4"/><path d="M12 20V22"/><path d="M4 12L2 12"/><path d="M22 12L20 12"/><path d="M19.7778 4.22266L17.5558 6.25424"/><path d="M4.22217 4.22266L6.44418 6.25424"/><path d="M6.44434 17.5557L4.22211 19.7779"/><path d="M19.7778 19.7773L17.5558 17.5551"/></g>'
|
|
27
|
+
},
|
|
28
|
+
"moon-linear": {
|
|
29
|
+
body: '<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12 22C17.5228 22 22 17.5228 22 12C22 11.5373 21.3065 11.4608 21.0672 11.8568C19.9289 13.7406 17.8615 15 15.5 15C11.9101 15 9 12.0899 9 8.5C9 6.13845 10.2594 4.07105 12.1432 2.93276C12.5392 2.69347 12.4627 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z"/>'
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
];
|
|
34
|
+
var THEME_ICONS = {
|
|
35
|
+
dark: { moving: "line-md:sunny-loop", still: "solar:sun-2-linear" },
|
|
36
|
+
light: { moving: "line-md:moon-loop", still: "solar:moon-linear" }
|
|
37
|
+
};
|
|
38
|
+
var registered = false;
|
|
39
|
+
var registerThemeIcons = /* @__PURE__ */ __name(() => {
|
|
40
|
+
if (registered) return;
|
|
41
|
+
for (const iconSet of THEME_ICON_SETS) addCollection(iconSet);
|
|
42
|
+
registered = true;
|
|
43
|
+
}, "registerThemeIcons");
|
|
44
|
+
THEME_ICON_SETS.flatMap(
|
|
45
|
+
({ prefix, icons }) => Object.keys(icons).map((name) => `${prefix}:${name}`)
|
|
46
|
+
);
|
|
47
|
+
var BUTTON_CSS = "relative size-5 cursor-pointer rounded-full after:absolute after:-inset-1 after:content-[''] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-crayola-c md:size-6";
|
|
48
|
+
var ICON_CSS = "text-tertiary hover:text-secondary size-full [&_path]:stroke-[1.5]";
|
|
49
|
+
var Theme = /* @__PURE__ */ __name(({ store: useThemeStore, labels, className = "", ...buttonProps }) => {
|
|
50
|
+
registerThemeIcons();
|
|
51
|
+
const theme = useThemeStore((state) => state.theme);
|
|
52
|
+
const toggleTheme = useThemeStore((state) => state.toggleTheme);
|
|
53
|
+
const isDark = theme === "dark";
|
|
54
|
+
const icons = THEME_ICONS[isDark ? "dark" : "light"];
|
|
55
|
+
const { toLight = "Switch to light theme", toDark = "Switch to dark theme" } = labels ?? {};
|
|
56
|
+
return /* @__PURE__ */ jsxs(
|
|
57
|
+
"button",
|
|
58
|
+
{
|
|
59
|
+
...buttonProps,
|
|
60
|
+
type: "button",
|
|
61
|
+
onClick: toggleTheme,
|
|
62
|
+
"aria-label": isDark ? toLight : toDark,
|
|
63
|
+
className: `${BUTTON_CSS} ${className}`,
|
|
64
|
+
children: [
|
|
65
|
+
/* @__PURE__ */ jsx(Icon, { icon: icons.moving, className: `${ICON_CSS} motion-reduce:hidden` }),
|
|
66
|
+
/* @__PURE__ */ jsx(Icon, { icon: icons.still, className: `${ICON_CSS} hidden motion-reduce:block` })
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
}, "Theme");
|
|
71
|
+
|
|
72
|
+
export { Theme };
|
|
73
|
+
//# sourceMappingURL=index.js.map
|
|
74
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/theme/theme-icons.ts","../../src/theme/Theme.tsx"],"names":[],"mappings":";;;;;AAYA,IAAM,eAAA,GAAiC;AAAA,EACrC;AAAA,IACE,MAAA,EAAQ,SAAA;AAAA,IACR,KAAA,EAAO,EAAA;AAAA,IACP,MAAA,EAAQ,EAAA;AAAA,IACR,KAAA,EAAO;AAAA,MACL,YAAA,EAAc;AAAA,QACZ,IAAA,EAAM;AAAA,OACR;AAAA,MACA,WAAA,EAAa;AAAA,QACX,IAAA,EAAM;AAAA;AACR;AACF,GACF;AAAA,EACA;AAAA,IACE,MAAA,EAAQ,OAAA;AAAA,IACR,KAAA,EAAO,EAAA;AAAA,IACP,MAAA,EAAQ,EAAA;AAAA,IACR,KAAA,EAAO;AAAA,MACL,cAAA,EAAgB;AAAA,QACd,IAAA,EAAM;AAAA,OACR;AAAA,MACA,aAAA,EAAe;AAAA,QACb,IAAA,EAAM;AAAA;AACR;AACF;AAEJ,CAAA;AAGO,IAAM,WAAA,GAAc;AAAA,EACzB,IAAA,EAAM,EAAE,MAAA,EAAQ,oBAAA,EAAsB,OAAO,oBAAA,EAAqB;AAAA,EAClE,KAAA,EAAO,EAAE,MAAA,EAAQ,mBAAA,EAAqB,OAAO,mBAAA;AAC/C,CAAA;AAEA,IAAI,UAAA,GAAa,KAAA;AAQV,IAAM,qCAAqB,MAAA,CAAA,MAAM;AACtC,EAAA,IAAI,UAAA,EAAY;AAEhB,EAAA,KAAA,MAAW,OAAA,IAAW,eAAA,EAAiB,aAAA,CAAc,OAAO,CAAA;AAC5D,EAAA,UAAA,GAAa,IAAA;AACf,CAAA,EALkC,oBAAA,CAAA;AAQF,eAAA,CAAgB,OAAA;AAAA,EAAQ,CAAC,EAAE,MAAA,EAAQ,KAAA,EAAM,KACvE,OAAO,IAAA,CAAK,KAAK,CAAA,CAAE,GAAA,CAAI,CAAC,IAAA,KAAS,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE;AACtD;ACvCA,IAAM,UAAA,GACJ,oMAAA;AACF,IAAM,QAAA,GAAW,oEAAA;AAUV,IAAM,KAAA,mBAAQ,MAAA,CAAA,CAAC,EAAE,KAAA,EAAO,aAAA,EAAe,QAAQ,SAAA,GAAY,EAAA,EAAI,GAAG,WAAA,EAAY,KAAc;AACjG,EAAA,kBAAA,EAAmB;AAEnB,EAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,CAAC,KAAA,KAAU,MAAM,KAAK,CAAA;AAClD,EAAA,MAAM,WAAA,GAAc,aAAA,CAAc,CAAC,KAAA,KAAU,MAAM,WAAW,CAAA;AAE9D,EAAA,MAAM,SAAS,KAAA,KAAU,MAAA;AACzB,EAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,MAAA,GAAS,MAAA,GAAS,OAAO,CAAA;AACnD,EAAA,MAAM,EAAE,OAAA,GAAU,uBAAA,EAAyB,SAAS,sBAAA,EAAuB,GAAI,UAAU,EAAC;AAE1F,EAAA,uBACE,IAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACE,GAAG,WAAA;AAAA,MACJ,IAAA,EAAK,QAAA;AAAA,MACL,OAAA,EAAS,WAAA;AAAA,MACT,YAAA,EAAY,SAAS,OAAA,GAAU,MAAA;AAAA,MAC/B,SAAA,EAAW,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA;AAAA,MAGrC,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,QAAK,IAAA,EAAM,KAAA,CAAM,QAAQ,SAAA,EAAW,CAAA,EAAG,QAAQ,CAAA,qBAAA,CAAA,EAAyB,CAAA;AAAA,wBACzE,GAAA,CAAC,QAAK,IAAA,EAAM,KAAA,CAAM,OAAO,SAAA,EAAW,CAAA,EAAG,QAAQ,CAAA,2BAAA,CAAA,EAA+B;AAAA;AAAA;AAAA,GAChF;AAEJ,CAAA,EAvBqB,OAAA","file":"index.js","sourcesContent":["import { addCollection, type IconifyJSON } from '@iconify/react';\n\n/*\n * The icons of the theme button. Iconify downloads an icon from its API the first time it is shown,\n * which cannot work offline and leaves the button empty until it arrives, so they are bundled here and\n * registered with Iconify (the same way as the toast icons, see `toast-icons.ts`).\n *\n * For each theme there are two: one that moves (`line-md`, drawn with SMIL and never stops) and a\n * still one (`solar`) for a person who asked for less motion.\n *\n * The data is what `https://api.iconify.design/<prefix>.json?icons=<name>` answers.\n */\nconst THEME_ICON_SETS: IconifyJSON[] = [\n {\n prefix: 'line-md',\n width: 24,\n height: 24,\n icons: {\n 'sunny-loop': {\n body: '<g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"><path stroke-dasharray=\"34\" d=\"M12 7c2.76 0 5 2.24 5 5c0 2.76 -2.24 5 -5 5c-2.76 0 -5 -2.24 -5 -5c0 -2.76 2.24 -5 5 -5Z\"><animate fill=\"freeze\" attributeName=\"stroke-dashoffset\" dur=\"0.4s\" values=\"34;0\"/></path><path d=\"M12 21v1M21 12h1M12 3v-1M3 12h-1\" opacity=\"0\"><animateTransform attributeName=\"transform\" dur=\"30s\" repeatCount=\"indefinite\" type=\"rotate\" values=\"0 12 12;360 12 12\"/><set fill=\"freeze\" attributeName=\"opacity\" begin=\"0.5s\" to=\"1\"/><animate fill=\"freeze\" attributeName=\"d\" begin=\"0.5s\" dur=\"0.2s\" values=\"M12 19v1M19 12h1M12 5v-1M5 12h-1;M12 21v1M21 12h1M12 3v-1M3 12h-1\"/></path><path d=\"M18.5 18.5l0.5 0.5M18.5 5.5l0.5 -0.5M5.5 5.5l-0.5 -0.5M5.5 18.5l-0.5 0.5\" opacity=\"0\"><animateTransform attributeName=\"transform\" dur=\"30s\" repeatCount=\"indefinite\" type=\"rotate\" values=\"0 12 12;360 12 12\"/><set fill=\"freeze\" attributeName=\"opacity\" begin=\"0.7s\" to=\"1\"/><animate fill=\"freeze\" attributeName=\"d\" begin=\"0.7s\" dur=\"0.2s\" values=\"M17 17l0.5 0.5M17 7l0.5 -0.5M7 7l-0.5 -0.5M7 17l-0.5 0.5;M18.5 18.5l0.5 0.5M18.5 5.5l0.5 -0.5M5.5 5.5l-0.5 -0.5M5.5 18.5l-0.5 0.5\"/></path></g>',\n },\n 'moon-loop': {\n body: '<path fill=\"none\" stroke=\"currentColor\" stroke-dasharray=\"56\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M7 6c0 6.08 4.92 11 11 11c0.53 0 1.05 -0.04 1.56 -0.11c-1.61 2.47 -4.39 4.11 -7.56 4.11c-4.97 0 -9 -4.03 -9 -9c0 -3.17 1.64 -5.95 4.11 -7.56c-0.07 0.51 -0.11 1.03 -0.11 1.56Z\"><animate fill=\"freeze\" attributeName=\"stroke-dashoffset\" dur=\"0.6s\" values=\"56;0\"/></path><g fill=\"currentColor\"><path d=\"M15.22 6.03l2.53 -1.94l-3.19 -0.09l-1.06 -3l-1.06 3l-3.19 0.09l2.53 1.94l-0.91 3.06l2.63 -1.81l2.63 1.81l-0.91 -3.06Z\" opacity=\"0\"><animate attributeName=\"opacity\" begin=\"0.7s\" dur=\"6s\" keyTimes=\"0;0.1;0.4;0.5;1\" repeatCount=\"indefinite\" values=\"0;1;1;0;0\"/></path><path d=\"M19.61 12.25l1.64 -1.25l-2.06 -0.05l-0.69 -1.95l-0.69 1.95l-2.06 0.05l1.64 1.25l-0.59 1.98l1.7 -1.17l1.7 1.17l-0.59 -1.98Z\" opacity=\"0\"><animate attributeName=\"opacity\" begin=\"0.7s\" dur=\"6s\" keyTimes=\"0;0.2;0.3;0.6;0.7;1\" repeatCount=\"indefinite\" values=\"0;0;1;1;0;0\"/></path><path d=\"M13.61 5.25l1.64 -1.25l-2.06 -0.05l-0.69 -1.95l-0.69 1.95l-2.06 0.05l1.64 1.25l-0.59 1.98l1.7 -1.17l1.7 1.17Z\" opacity=\"0\"><animate attributeName=\"opacity\" begin=\"3.7s\" dur=\"6s\" keyTimes=\"0;0.1;0.4;0.5;1\" repeatCount=\"indefinite\" values=\"0;1;1;0;0\"/></path><path d=\"M20.83 9.73l1.88 -1.44l-2.37 -0.07l-0.79 -2.22l-0.79 2.23l-2.37 0.07l1.88 1.44l-0.68 2.27l1.95 -1.34l1.95 1.34Z\" opacity=\"0\"><animate attributeName=\"opacity\" begin=\"3.7s\" dur=\"6s\" keyTimes=\"0;0.2;0.3;0.6;0.7;1\" repeatCount=\"indefinite\" values=\"0;0;1;1;0;0\"/></path></g>',\n },\n },\n },\n {\n prefix: 'solar',\n width: 24,\n height: 24,\n icons: {\n 'sun-2-linear': {\n body: '<g fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"1.5\"><circle cx=\"12\" cy=\"12\" r=\"5\"/><path d=\"M12 2V4\"/><path d=\"M12 20V22\"/><path d=\"M4 12L2 12\"/><path d=\"M22 12L20 12\"/><path d=\"M19.7778 4.22266L17.5558 6.25424\"/><path d=\"M4.22217 4.22266L6.44418 6.25424\"/><path d=\"M6.44434 17.5557L4.22211 19.7779\"/><path d=\"M19.7778 19.7773L17.5558 17.5551\"/></g>',\n },\n 'moon-linear': {\n body: '<path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.5\" d=\"M12 22C17.5228 22 22 17.5228 22 12C22 11.5373 21.3065 11.4608 21.0672 11.8568C19.9289 13.7406 17.8615 15 15.5 15C11.9101 15 9 12.0899 9 8.5C9 6.13845 10.2594 4.07105 12.1432 2.93276C12.5392 2.69347 12.4627 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z\"/>',\n },\n },\n },\n];\n\n/** What the button shows while the theme is dark (a sun: it would switch to light) and light (a moon). */\nexport const THEME_ICONS = {\n dark: { moving: 'line-md:sunny-loop', still: 'solar:sun-2-linear' },\n light: { moving: 'line-md:moon-loop', still: 'solar:moon-linear' },\n} as const;\n\nlet registered = false;\n\n/**\n * Registers the icons above with Iconify. `Theme` calls it when it renders, not when this file is\n * imported: an app that never renders the button never runs it, and nothing depends on the bundler\n * keeping an import that is only there for its effect (see `toast-icons.ts`). Calling it again is\n * harmless.\n */\nexport const registerThemeIcons = () => {\n if (registered) return;\n\n for (const iconSet of THEME_ICON_SETS) addCollection(iconSet);\n registered = true;\n};\n\n/** Every icon name registered above, e.g. `line-md:sunny-loop`. */\nexport const THEME_ICON_NAMES = THEME_ICON_SETS.flatMap(({ prefix, icons }) =>\n Object.keys(icons).map((name) => `${prefix}:${name}`),\n);\n","import type { TThemeStoreHook } from '@beautinique/frontend-stores';\nimport { Icon } from '@iconify/react';\nimport type { ComponentProps } from 'react';\n\nimport { registerThemeIcons, THEME_ICONS } from './theme-icons.js';\n\nexport interface ITheme extends Omit<\n ComponentProps<'button'>,\n 'children' | 'onClick' | 'type' | 'aria-label'\n> {\n /** The theme store of the app: what `createThemeStore()` of `@beautinique/frontend-stores` gave it. */\n store: TThemeStoreHook;\n /** What the button says to assistive technology, for the theme it would switch to. */\n labels?: {\n /** @default 'Switch to light theme' */\n toLight?: string;\n /** @default 'Switch to dark theme' */\n toDark?: string;\n };\n}\n\n// The hit area is bigger than the icon (the icon is 20px on a phone): the `after` box is a part of the\n// button, so a thumb that lands next to the icon still presses it, and nothing around it moves.\n// No `outline-hidden`: in Tailwind v4 it sets `--tw-outline-style: none`, which the\n// `focus-visible:outline-2` uses for its style, so the ring would never be drawn. A button only shows\n// the browser's own ring for the keyboard anyway (`:focus-visible`), never for a click.\nconst BUTTON_CSS =\n \"relative size-5 cursor-pointer rounded-full after:absolute after:-inset-1 after:content-[''] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-crayola-c md:size-6\";\nconst ICON_CSS = 'text-tertiary hover:text-secondary size-full [&_path]:stroke-[1.5]';\n\n/**\n * A button that switches between the dark and the light theme. It shows the theme it would switch\n * to: a sun while the theme is dark, a moon while it is light. It only changes the store; putting the\n * theme on the page (a class on `<html>`) is the app's.\n *\n * The icons move; for a person who asked their system for less motion (`prefers-reduced-motion`)\n * the button shows still ones instead.\n */\nexport const Theme = ({ store: useThemeStore, labels, className = '', ...buttonProps }: ITheme) => {\n registerThemeIcons();\n\n const theme = useThemeStore((state) => state.theme);\n const toggleTheme = useThemeStore((state) => state.toggleTheme);\n\n const isDark = theme === 'dark';\n const icons = THEME_ICONS[isDark ? 'dark' : 'light'];\n const { toLight = 'Switch to light theme', toDark = 'Switch to dark theme' } = labels ?? {};\n\n return (\n <button\n {...buttonProps}\n type=\"button\"\n onClick={toggleTheme}\n aria-label={isDark ? toLight : toDark}\n className={`${BUTTON_CSS} ${className}`}\n >\n {/* Both are in the page and css picks one: no script has to ask the system about motion. */}\n <Icon icon={icons.moving} className={`${ICON_CSS} motion-reduce:hidden`} />\n <Icon icon={icons.still} className={`${ICON_CSS} hidden motion-reduce:block`} />\n </button>\n );\n};\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** What the button shows while the theme is dark (a sun: it would switch to light) and light (a moon). */
|
|
2
|
+
export declare const THEME_ICONS: {
|
|
3
|
+
readonly dark: {
|
|
4
|
+
readonly moving: "line-md:sunny-loop";
|
|
5
|
+
readonly still: "solar:sun-2-linear";
|
|
6
|
+
};
|
|
7
|
+
readonly light: {
|
|
8
|
+
readonly moving: "line-md:moon-loop";
|
|
9
|
+
readonly still: "solar:moon-linear";
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Registers the icons above with Iconify. `Theme` calls it when it renders, not when this file is
|
|
14
|
+
* imported: an app that never renders the button never runs it, and nothing depends on the bundler
|
|
15
|
+
* keeping an import that is only there for its effect (see `toast-icons.ts`). Calling it again is
|
|
16
|
+
* harmless.
|
|
17
|
+
*/
|
|
18
|
+
export declare const registerThemeIcons: () => void;
|
|
19
|
+
/** Every icon name registered above, e.g. `line-md:sunny-loop`. */
|
|
20
|
+
export declare const THEME_ICON_NAMES: string[];
|
|
21
|
+
//# sourceMappingURL=theme-icons.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-icons.d.cts","sourceRoot":"","sources":["../../src/theme/theme-icons.ts"],"names":[],"mappings":"AAyCA,0GAA0G;AAC1G,eAAO,MAAM,WAAW;;;;;;;;;CAGd,CAAC;AAIX;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,YAK9B,CAAC;AAEF,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,UAE5B,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** What the button shows while the theme is dark (a sun: it would switch to light) and light (a moon). */
|
|
2
|
+
export declare const THEME_ICONS: {
|
|
3
|
+
readonly dark: {
|
|
4
|
+
readonly moving: "line-md:sunny-loop";
|
|
5
|
+
readonly still: "solar:sun-2-linear";
|
|
6
|
+
};
|
|
7
|
+
readonly light: {
|
|
8
|
+
readonly moving: "line-md:moon-loop";
|
|
9
|
+
readonly still: "solar:moon-linear";
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Registers the icons above with Iconify. `Theme` calls it when it renders, not when this file is
|
|
14
|
+
* imported: an app that never renders the button never runs it, and nothing depends on the bundler
|
|
15
|
+
* keeping an import that is only there for its effect (see `toast-icons.ts`). Calling it again is
|
|
16
|
+
* harmless.
|
|
17
|
+
*/
|
|
18
|
+
export declare const registerThemeIcons: () => void;
|
|
19
|
+
/** Every icon name registered above, e.g. `line-md:sunny-loop`. */
|
|
20
|
+
export declare const THEME_ICON_NAMES: string[];
|
|
21
|
+
//# sourceMappingURL=theme-icons.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme-icons.d.ts","sourceRoot":"","sources":["../../src/theme/theme-icons.ts"],"names":[],"mappings":"AAyCA,0GAA0G;AAC1G,eAAO,MAAM,WAAW;;;;;;;;;CAGd,CAAC;AAIX;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,YAK9B,CAAC;AAEF,mEAAmE;AACnE,eAAO,MAAM,gBAAgB,UAE5B,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ComponentProps, ReactNode } from 'react';
|
|
2
|
+
export interface IBadge extends Omit<ComponentProps<'span'>, 'children' | 'content'> {
|
|
3
|
+
/**
|
|
4
|
+
* What the badge shows: text, a number, or any React content (an icon, a few elements). A badge
|
|
5
|
+
* with nothing to show (`null`, `undefined`, `false` or an empty string) renders nothing at all,
|
|
6
|
+
* not an empty pill; `0` is something to show.
|
|
7
|
+
*/
|
|
8
|
+
content: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
/** A small pill with a label, a count or a status. Any attribute of a `<span>` is passed on. */
|
|
11
|
+
export declare const Badge: ({ content, className, ...spanProps }: IBadge) => import("react").JSX.Element | null;
|
|
12
|
+
//# sourceMappingURL=Badge.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Badge.d.cts","sourceRoot":"","sources":["../../src/ui/Badge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvD,MAAM,WAAW,MAAO,SAAQ,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAClF;;;;OAIG;IACH,OAAO,EAAE,SAAS,CAAC;CACpB;AAKD,gGAAgG;AAChG,eAAO,MAAM,KAAK,GAAI,sCAA2C,MAAM,uCAK7D,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ComponentProps, ReactNode } from 'react';
|
|
2
|
+
export interface IBadge extends Omit<ComponentProps<'span'>, 'children' | 'content'> {
|
|
3
|
+
/**
|
|
4
|
+
* What the badge shows: text, a number, or any React content (an icon, a few elements). A badge
|
|
5
|
+
* with nothing to show (`null`, `undefined`, `false` or an empty string) renders nothing at all,
|
|
6
|
+
* not an empty pill; `0` is something to show.
|
|
7
|
+
*/
|
|
8
|
+
content: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
/** A small pill with a label, a count or a status. Any attribute of a `<span>` is passed on. */
|
|
11
|
+
export declare const Badge: ({ content, className, ...spanProps }: IBadge) => import("react").JSX.Element | null;
|
|
12
|
+
//# sourceMappingURL=Badge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../src/ui/Badge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvD,MAAM,WAAW,MAAO,SAAQ,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAClF;;;;OAIG;IACH,OAAO,EAAE,SAAS,CAAC;CACpB;AAKD,gGAAgG;AAChG,eAAO,MAAM,KAAK,GAAI,sCAA2C,MAAM,uCAK7D,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ComponentProps } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Any attribute of an `<hr>` can be given (a `role`, `aria-*`, an `id`), but no children: an `<hr>`
|
|
4
|
+
* is a void element, and React throws when it is given some.
|
|
5
|
+
*/
|
|
6
|
+
export type TDivider = Omit<ComponentProps<'hr'>, 'children' | 'dangerouslySetInnerHTML'>;
|
|
7
|
+
/**
|
|
8
|
+
* A horizontal line between two parts of a page. It is an `<hr>`, so assistive technology reads it
|
|
9
|
+
* as a separator; to hide it from them (a purely visual line) give it `aria-hidden`.
|
|
10
|
+
*/
|
|
11
|
+
export declare const Divider: ({ className, ...hrProps }: TDivider) => import("react").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=Divider.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Divider.d.cts","sourceRoot":"","sources":["../../src/ui/Divider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAE5C;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,yBAAyB,CAAC,CAAC;AAI1F;;;GAGG;AACH,eAAO,MAAM,OAAO,GAAI,2BAAgC,QAAQ,gCAE/D,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ComponentProps } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Any attribute of an `<hr>` can be given (a `role`, `aria-*`, an `id`), but no children: an `<hr>`
|
|
4
|
+
* is a void element, and React throws when it is given some.
|
|
5
|
+
*/
|
|
6
|
+
export type TDivider = Omit<ComponentProps<'hr'>, 'children' | 'dangerouslySetInnerHTML'>;
|
|
7
|
+
/**
|
|
8
|
+
* A horizontal line between two parts of a page. It is an `<hr>`, so assistive technology reads it
|
|
9
|
+
* as a separator; to hide it from them (a purely visual line) give it `aria-hidden`.
|
|
10
|
+
*/
|
|
11
|
+
export declare const Divider: ({ className, ...hrProps }: TDivider) => import("react").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=Divider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Divider.d.ts","sourceRoot":"","sources":["../../src/ui/Divider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAE5C;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,UAAU,GAAG,yBAAyB,CAAC,CAAC;AAI1F;;;GAGG;AACH,eAAO,MAAM,OAAO,GAAI,2BAAgC,QAAQ,gCAE/D,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ComponentPropsWithRef, ElementType, ReactNode } from 'react';
|
|
2
|
+
/** `accent`: the blue gradient of the brand. `silver`: the quiet grey one. */
|
|
3
|
+
export type TGradientTextType = 'accent' | 'silver';
|
|
4
|
+
/** The text is given as `text`, or as `children` (anything React can show), not both. */
|
|
5
|
+
type TGradientTextContent = {
|
|
6
|
+
text: string;
|
|
7
|
+
children?: never;
|
|
8
|
+
} | {
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
text?: never;
|
|
11
|
+
};
|
|
12
|
+
interface IGradientTextOwnProps<TAs extends ElementType> {
|
|
13
|
+
/**
|
|
14
|
+
* What renders the text: an element (`'a'`, `'p'`, ...) or a component, e.g. the `Link` of the
|
|
15
|
+
* router, which then gets its own props (`to`) next to these.
|
|
16
|
+
* @default 'span'
|
|
17
|
+
*/
|
|
18
|
+
as?: TAs;
|
|
19
|
+
type: TGradientTextType;
|
|
20
|
+
className?: string;
|
|
21
|
+
}
|
|
22
|
+
export type IGradientText<TAs extends ElementType = 'span'> = IGradientTextOwnProps<TAs> & TGradientTextContent & Omit<ComponentPropsWithRef<TAs>, 'as' | 'type' | 'className' | 'text' | 'children'>;
|
|
23
|
+
/**
|
|
24
|
+
* Text filled with a gradient. A link is a text that is rendered by a link component:
|
|
25
|
+
* `<GradientText as={Link} to="/terms" type="accent" text="Terms" />`; the router is the app's, not
|
|
26
|
+
* this package's.
|
|
27
|
+
*/
|
|
28
|
+
export declare const GradientText: <TAs extends ElementType = "span">({ as, type, text, children, className, ...rest }: IGradientText<TAs>) => import("react").JSX.Element;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=GradientText.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GradientText.d.cts","sourceRoot":"","sources":["../../src/ui/GradientText.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE3E,8EAA8E;AAC9E,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEpD,yFAAyF;AACzF,KAAK,oBAAoB,GACvB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,IAAI,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAE7E,UAAU,qBAAqB,CAAC,GAAG,SAAS,WAAW;IACrD;;;;OAIG;IACH,EAAE,CAAC,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,iBAAiB,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,aAAa,CAAC,GAAG,SAAS,WAAW,GAAG,MAAM,IAAI,qBAAqB,CAAC,GAAG,CAAC,GACtF,oBAAoB,GACpB,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,GAAG,UAAU,CAAC,CAAC;AAatF;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,GAAG,SAAS,WAAW,GAAG,MAAM,EAAE,kDAO5D,aAAa,CAAC,GAAG,CAAC,gCAWpB,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ComponentPropsWithRef, ElementType, ReactNode } from 'react';
|
|
2
|
+
/** `accent`: the blue gradient of the brand. `silver`: the quiet grey one. */
|
|
3
|
+
export type TGradientTextType = 'accent' | 'silver';
|
|
4
|
+
/** The text is given as `text`, or as `children` (anything React can show), not both. */
|
|
5
|
+
type TGradientTextContent = {
|
|
6
|
+
text: string;
|
|
7
|
+
children?: never;
|
|
8
|
+
} | {
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
text?: never;
|
|
11
|
+
};
|
|
12
|
+
interface IGradientTextOwnProps<TAs extends ElementType> {
|
|
13
|
+
/**
|
|
14
|
+
* What renders the text: an element (`'a'`, `'p'`, ...) or a component, e.g. the `Link` of the
|
|
15
|
+
* router, which then gets its own props (`to`) next to these.
|
|
16
|
+
* @default 'span'
|
|
17
|
+
*/
|
|
18
|
+
as?: TAs;
|
|
19
|
+
type: TGradientTextType;
|
|
20
|
+
className?: string;
|
|
21
|
+
}
|
|
22
|
+
export type IGradientText<TAs extends ElementType = 'span'> = IGradientTextOwnProps<TAs> & TGradientTextContent & Omit<ComponentPropsWithRef<TAs>, 'as' | 'type' | 'className' | 'text' | 'children'>;
|
|
23
|
+
/**
|
|
24
|
+
* Text filled with a gradient. A link is a text that is rendered by a link component:
|
|
25
|
+
* `<GradientText as={Link} to="/terms" type="accent" text="Terms" />`; the router is the app's, not
|
|
26
|
+
* this package's.
|
|
27
|
+
*/
|
|
28
|
+
export declare const GradientText: <TAs extends ElementType = "span">({ as, type, text, children, className, ...rest }: IGradientText<TAs>) => import("react").JSX.Element;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=GradientText.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GradientText.d.ts","sourceRoot":"","sources":["../../src/ui/GradientText.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE3E,8EAA8E;AAC9E,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEpD,yFAAyF;AACzF,KAAK,oBAAoB,GACvB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,IAAI,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAE7E,UAAU,qBAAqB,CAAC,GAAG,SAAS,WAAW;IACrD;;;;OAIG;IACH,EAAE,CAAC,EAAE,GAAG,CAAC;IACT,IAAI,EAAE,iBAAiB,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,aAAa,CAAC,GAAG,SAAS,WAAW,GAAG,MAAM,IAAI,qBAAqB,CAAC,GAAG,CAAC,GACtF,oBAAoB,GACpB,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,GAAG,UAAU,CAAC,CAAC;AAatF;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAI,GAAG,SAAS,WAAW,GAAG,MAAM,EAAE,kDAO5D,aAAa,CAAC,GAAG,CAAC,gCAWpB,CAAC"}
|