Compare commits

...

11 Commits

Author SHA1 Message Date
b163fdaa62 update styles, v0.1.17
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2026-02-24 10:37:36 +01:00
ec63a10027 update ci
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2026-02-24 10:14:08 +01:00
5ada69773c update ci, datepicker, v0.1.16
Some checks failed
continuous-integration/drone/push Build is failing
2026-02-24 10:06:41 +01:00
370d6e7e0a v0.1.15
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing
2026-02-23 23:53:32 +01:00
44dd5d5deb v0.1.14
Some checks failed
continuous-integration/drone/push Build encountered an error
continuous-integration/drone/tag Build encountered an error
2026-02-23 23:51:42 +01:00
8d3ca5a281 fix ci
Some checks failed
continuous-integration/drone/push Build encountered an error
2026-02-23 23:51:16 +01:00
1d5113d209 fix datepicker css, v0.1.13
Some checks failed
continuous-integration/drone/tag Build is failing
continuous-integration/drone/push Build is passing
2026-02-23 23:48:58 +01:00
f71e773a3a update drone
All checks were successful
continuous-integration/drone/push Build is passing
2026-02-23 23:34:04 +01:00
4921afe296 fix date picker highlighting, v0.1.12
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/promote/production Build is passing
2026-02-23 23:29:06 +01:00
5cc3e3646c make accent overridable, v0.1.11
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/promote/production Build is passing
2026-02-23 22:59:57 +01:00
29a4e8c2ee add width, v0.1.10
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/promote/production Build is passing
2026-02-23 19:57:19 +01:00
14 changed files with 206 additions and 48 deletions

View File

@@ -13,24 +13,18 @@ trigger:
steps: steps:
- name: install - name: install
image: node:22 image: node:25
commands: commands:
- corepack enable
- corepack prepare yarn@1.22.22 --activate
- yarn install --frozen-lockfile - yarn install --frozen-lockfile
- name: lint - name: lint
image: node:22 image: node:25
commands: commands:
- corepack enable
- corepack prepare yarn@1.22.22 --activate
- yarn lint - yarn lint
- name: build - name: build
image: node:22 image: node:25
commands: commands:
- corepack enable
- corepack prepare yarn@1.22.22 --activate
- yarn build - yarn build
--- ---
@@ -39,22 +33,18 @@ type: docker
name: web-ui-publish name: web-ui-publish
trigger: trigger:
branch:
- main
event: event:
- promote - tag
target: ref:
- production - refs/tags/v*
steps: steps:
- name: publish-npm - name: publish-npm
image: node:22 image: node:25
environment: environment:
NEXUS_NPM_TOKEN: NEXUS_NPM_TOKEN:
from_secret: nexus_npm_token from_secret: nexus_npm_token
commands: commands:
- corepack enable
- corepack prepare yarn@1.22.22 --activate
- yarn install --frozen-lockfile - yarn install --frozen-lockfile
- npm config set //nexus.beatrice.wtf/repository/npm-hosted/:_authToken "$NEXUS_NPM_TOKEN" - npm config set //nexus.beatrice.wtf/repository/npm-hosted/:_authToken "$NEXUS_NPM_TOKEN"
- yarn publish:nexus - yarn publish:nexus

View File

@@ -1,6 +1,6 @@
{ {
"name": "@panic/web-ui", "name": "@panic/web-ui",
"version": "0.1.9", "version": "0.1.17",
"license": "AGPL-3.0-only", "license": "AGPL-3.0-only",
"description": "Core components for panic.haus web applications", "description": "Core components for panic.haus web applications",
"type": "module", "type": "module",

View File

@@ -39,6 +39,12 @@ const meta = {
control: 'inline-radio', control: 'inline-radio',
table: { type: { summary: "'sm' | 'md' | 'lg' | 'full'" } }, table: { type: { summary: "'sm' | 'md' | 'lg' | 'full'" } },
}, },
width: {
description: 'Button width behavior.',
options: ['sm', 'md', 'lg', 'full'],
control: 'inline-radio',
table: { type: { summary: "'sm' | 'md' | 'lg' | 'full'" } },
},
to: { to: {
description: 'Navigation path. When set, the component renders a `<Link>`.', description: 'Navigation path. When set, the component renders a `<Link>`.',
control: 'text', control: 'text',
@@ -80,6 +86,7 @@ const meta = {
type: 'solid', type: 'solid',
variant: 'primary', variant: 'primary',
size: 'md', size: 'md',
width: 'md',
label: 'Save', label: 'Save',
}, },
} satisfies Meta<typeof Button>; } satisfies Meta<typeof Button>;
@@ -132,7 +139,7 @@ export const SizeMatrix: Story = {
<Button {...args} size="sm" label="Small" /> <Button {...args} size="sm" label="Small" />
<Button {...args} size="md" label="Medium" /> <Button {...args} size="md" label="Medium" />
<Button {...args} size="lg" label="Large" /> <Button {...args} size="lg" label="Large" />
<Button {...args} size="full" label="Full width" /> <Button {...args} size="md" width="full" label="Full width" />
</div> </div>
), ),
}; };

View File

@@ -11,6 +11,7 @@ type ButtonProps = {
type: ButtonType; type: ButtonType;
variant?: ButtonVariant; variant?: ButtonVariant;
size?: ComponentSize; size?: ComponentSize;
width?: ComponentSize;
to?: string; to?: string;
htmlType?: NativeButtonType; htmlType?: NativeButtonType;
onClick?: MouseEventHandler<HTMLElement>; onClick?: MouseEventHandler<HTMLElement>;
@@ -24,14 +25,14 @@ const SIZE_CLASS: Record<ComponentSize, string> = {
sm: 'h-8 px-3 text-xs', sm: 'h-8 px-3 text-xs',
md: 'h-10 px-4 text-sm', md: 'h-10 px-4 text-sm',
lg: 'h-12 px-5 text-base', lg: 'h-12 px-5 text-base',
full: 'h-10 w-full px-4 text-sm', full: 'h-10 px-4 text-sm',
}; };
const ICON_ONLY_SIZE_CLASS: Record<ComponentSize, string> = { const ICON_ONLY_SIZE_CLASS: Record<ComponentSize, string> = {
sm: 'h-8 w-8 !p-0', sm: 'h-8 w-8 !p-0',
md: 'h-10 w-10 !p-0', md: 'h-10 w-10 !p-0',
lg: 'h-12 w-12 !p-0', lg: 'h-12 w-12 !p-0',
full: 'h-10 w-full !p-0', full: 'h-10 w-10 !p-0',
}; };
const ICON_CLASS: Record<ComponentSize, string> = { const ICON_CLASS: Record<ComponentSize, string> = {
@@ -48,6 +49,13 @@ const ICON_ONLY_CLASS: Record<ComponentSize, string> = {
full: 'h-5 w-5', full: 'h-5 w-5',
}; };
const WIDTH_CLASS: Record<ComponentSize, string> = {
sm: 'max-w-xs',
md: '',
lg: 'max-w-md',
full: 'w-full max-w-none',
};
const TYPE_CLASS: Record<ButtonType, string> = { const TYPE_CLASS: Record<ButtonType, string> = {
solid: 'btn-solid', solid: 'btn-solid',
outlined: 'btn-outlined', outlined: 'btn-outlined',
@@ -73,6 +81,7 @@ export function Button({
type, type,
variant, variant,
size = 'md', size = 'md',
width = 'md',
to, to,
htmlType = 'button', htmlType = 'button',
onClick, onClick,
@@ -87,6 +96,7 @@ export function Button({
TYPE_CLASS[type], TYPE_CLASS[type],
VARIANT_CLASS[resolvedVariant], VARIANT_CLASS[resolvedVariant],
isIconOnly ? ICON_ONLY_SIZE_CLASS[size] : SIZE_CLASS[size], isIconOnly ? ICON_ONLY_SIZE_CLASS[size] : SIZE_CLASS[size],
WIDTH_CLASS[width],
Icon && label ? 'gap-1.5' : '', Icon && label ? 'gap-1.5' : '',
disabled ? 'pointer-events-none cursor-not-allowed opacity-45 saturate-50' : '', disabled ? 'pointer-events-none cursor-not-allowed opacity-45 saturate-50' : '',
className, className,

View File

@@ -38,6 +38,12 @@ const meta = {
control: 'inline-radio', control: 'inline-radio',
table: { type: { summary: "'sm' | 'md' | 'lg' | 'full'" } }, table: { type: { summary: "'sm' | 'md' | 'lg' | 'full'" } },
}, },
width: {
description: 'Input width constraint.',
options: ['sm', 'md', 'lg', 'full'],
control: 'inline-radio',
table: { type: { summary: "'sm' | 'md' | 'lg' | 'full'" } },
},
layout: { layout: {
description: 'Label/input layout mode.', description: 'Label/input layout mode.',
options: ['stacked', 'inline'], options: ['stacked', 'inline'],
@@ -105,6 +111,7 @@ const meta = {
type: 'datetime-local', type: 'datetime-local',
value: '', value: '',
size: 'md', size: 'md',
width: 'md',
layout: 'stacked', layout: 'stacked',
}, },
} satisfies Meta<typeof DatePicker>; } satisfies Meta<typeof DatePicker>;
@@ -224,6 +231,7 @@ export const SizeMatrix: Story = {
{...args} {...args}
value={value} value={value}
size="full" size="full"
width="full"
onChange={(event) => setValue(event.target.value)} onChange={(event) => setValue(event.target.value)}
/> />
</div> </div>

View File

@@ -9,6 +9,7 @@ export type DatePickerProps = {
placeholder?: string; placeholder?: string;
type: DatePickerKind; type: DatePickerKind;
size?: ComponentSize; size?: ComponentSize;
width?: ComponentSize;
layout?: Layout; layout?: Layout;
value: string; value: string;
name?: string; name?: string;
@@ -28,6 +29,7 @@ export function DatePicker({
placeholder = '', placeholder = '',
type, type,
size = 'md', size = 'md',
width = 'md',
layout = 'stacked', layout = 'stacked',
value, value,
name, name,
@@ -41,12 +43,12 @@ export function DatePicker({
className = '', className = '',
inputClassName = '', inputClassName = '',
}: Readonly<DatePickerProps>) { }: Readonly<DatePickerProps>) {
const containerSizeClass = { const containerWidthClass = {
sm: 'max-w-xs', sm: 'max-w-xs',
md: 'max-w-sm', md: 'max-w-sm',
lg: 'max-w-md', lg: 'max-w-md',
full: 'max-w-none', full: 'max-w-none',
}[size]; }[width];
const inputSizeClass = { const inputSizeClass = {
sm: 'h-8 !text-xs', sm: 'h-8 !text-xs',
@@ -63,7 +65,7 @@ export function DatePicker({
return ( return (
<label <label
className={`${wrapperClass} text-sm font-medium ${disabled ? 'ui-label-disabled' : 'ui-label'} ${containerSizeClass} ${className}`.trim()} className={`${wrapperClass} text-sm font-medium ${disabled ? 'ui-label-disabled' : 'ui-label'} ${containerWidthClass} ${className}`.trim()}
> >
{label ? <span className={labelClass}>{label}</span> : null} {label ? <span className={labelClass}>{label}</span> : null}
<div className={inputWrapperClass}> <div className={inputWrapperClass}>

View File

@@ -42,6 +42,12 @@ const meta = {
control: 'inline-radio', control: 'inline-radio',
table: { type: { summary: "'sm' | 'md' | 'lg' | 'full'" } }, table: { type: { summary: "'sm' | 'md' | 'lg' | 'full'" } },
}, },
width: {
description: 'Control width constraint.',
options: ['sm', 'md', 'lg', 'full'],
control: 'inline-radio',
table: { type: { summary: "'sm' | 'md' | 'lg' | 'full'" } },
},
layout: { layout: {
description: 'Label/control layout mode.', description: 'Label/control layout mode.',
options: ['stacked', 'inline'], options: ['stacked', 'inline'],
@@ -84,6 +90,7 @@ const meta = {
value: 'draft', value: 'draft',
choices, choices,
size: 'md', size: 'md',
width: 'md',
layout: 'stacked', layout: 'stacked',
}, },
} satisfies Meta<typeof Dropdown>; } satisfies Meta<typeof Dropdown>;
@@ -147,7 +154,14 @@ export const SizeMatrix: Story = {
<Dropdown {...args} value={value} size="sm" label="Small" onChange={setValue} /> <Dropdown {...args} value={value} size="sm" label="Small" onChange={setValue} />
<Dropdown {...args} value={value} size="md" label="Medium" onChange={setValue} /> <Dropdown {...args} value={value} size="md" label="Medium" onChange={setValue} />
<Dropdown {...args} value={value} size="lg" label="Large" onChange={setValue} /> <Dropdown {...args} value={value} size="lg" label="Large" onChange={setValue} />
<Dropdown {...args} value={value} size="full" label="Full" onChange={setValue} /> <Dropdown
{...args}
value={value}
size="full"
width="full"
label="Full"
onChange={setValue}
/>
</div> </div>
); );
}, },

View File

@@ -14,6 +14,7 @@ type DropdownProps = {
value: string; value: string;
choices: DropdownChoice[]; choices: DropdownChoice[];
size?: ComponentSize; size?: ComponentSize;
width?: ComponentSize;
layout?: DropdownLayout; layout?: DropdownLayout;
disabled?: boolean; disabled?: boolean;
required?: boolean; required?: boolean;
@@ -28,6 +29,7 @@ export function Dropdown({
value, value,
choices, choices,
size = 'md', size = 'md',
width = 'md',
layout = 'stacked', layout = 'stacked',
disabled = false, disabled = false,
required = false, required = false,
@@ -36,12 +38,12 @@ export function Dropdown({
className = '', className = '',
selectClassName = '', selectClassName = '',
}: Readonly<DropdownProps>) { }: Readonly<DropdownProps>) {
const containerSizeClass = { const containerWidthClass = {
sm: 'max-w-xs', sm: 'max-w-xs',
md: 'max-w-sm', md: 'max-w-sm',
lg: 'max-w-md', lg: 'max-w-md',
full: 'max-w-none', full: 'max-w-none',
}[size]; }[width];
const selectSizeClass = { const selectSizeClass = {
sm: 'h-8 !text-xs', sm: 'h-8 !text-xs',
@@ -62,7 +64,7 @@ export function Dropdown({
return ( return (
<label <label
className={`${wrapperClass} text-sm font-medium ${disabled ? 'ui-label-disabled' : 'ui-label'} ${containerSizeClass} ${className}`.trim()} className={`${wrapperClass} text-sm font-medium ${disabled ? 'ui-label-disabled' : 'ui-label'} ${containerWidthClass} ${className}`.trim()}
> >
{label ? <span className={labelClass}>{label}</span> : null} {label ? <span className={labelClass}>{label}</span> : null}
<div className={selectWrapperClass}> <div className={selectWrapperClass}>

View File

@@ -80,6 +80,7 @@ export const WithActions: Story = {
value={title} value={title}
onChange={(event) => setTitle(event.target.value)} onChange={(event) => setTitle(event.target.value)}
size="full" size="full"
width="full"
/> />
</div> </div>
<Dropdown <Dropdown

View File

@@ -38,6 +38,12 @@ const meta = {
control: 'inline-radio', control: 'inline-radio',
table: { type: { summary: "'sm' | 'md' | 'lg' | 'full'" } }, table: { type: { summary: "'sm' | 'md' | 'lg' | 'full'" } },
}, },
width: {
description: 'Input width constraint.',
options: ['sm', 'md', 'lg', 'full'],
control: 'inline-radio',
table: { type: { summary: "'sm' | 'md' | 'lg' | 'full'" } },
},
layout: { layout: {
description: 'Label/input layout mode.', description: 'Label/input layout mode.',
options: ['stacked', 'inline'], options: ['stacked', 'inline'],
@@ -107,6 +113,7 @@ const meta = {
placeholder: 'name@example.com', placeholder: 'name@example.com',
value: '', value: '',
size: 'md', size: 'md',
width: 'md',
layout: 'stacked', layout: 'stacked',
}, },
} satisfies Meta<typeof InputField>; } satisfies Meta<typeof InputField>;
@@ -229,6 +236,7 @@ export const SizeMatrix: Story = {
{...args} {...args}
value={value} value={value}
size="full" size="full"
width="full"
onChange={(event) => setValue(event.target.value)} onChange={(event) => setValue(event.target.value)}
/> />
</div> </div>

View File

@@ -12,6 +12,7 @@ type InputFieldProps = {
placeholder?: string; placeholder?: string;
type: InputKind; type: InputKind;
size?: ComponentSize; size?: ComponentSize;
width?: ComponentSize;
layout?: Layout; layout?: Layout;
value: string; value: string;
name?: string; name?: string;
@@ -31,6 +32,7 @@ export function InputField({
placeholder = '', placeholder = '',
type, type,
size = 'md', size = 'md',
width = 'md',
layout = 'stacked', layout = 'stacked',
value, value,
name, name,
@@ -45,12 +47,12 @@ export function InputField({
inputClassName = '', inputClassName = '',
}: Readonly<InputFieldProps>) { }: Readonly<InputFieldProps>) {
const [showPassword, setShowPassword] = useState(false); const [showPassword, setShowPassword] = useState(false);
const containerSizeClass = { const containerWidthClass = {
sm: 'max-w-xs', sm: 'max-w-xs',
md: 'max-w-sm', md: 'max-w-sm',
lg: 'max-w-md', lg: 'max-w-md',
full: 'max-w-none', full: 'max-w-none',
}[size]; }[width];
const inputSizeClass = { const inputSizeClass = {
sm: 'h-8 !text-xs', sm: 'h-8 !text-xs',
@@ -69,7 +71,7 @@ export function InputField({
return ( return (
<label <label
className={`${wrapperClass} text-sm font-medium ${disabled ? 'ui-label-disabled' : 'ui-label'} ${containerSizeClass} ${className}`.trim()} className={`${wrapperClass} text-sm font-medium ${disabled ? 'ui-label-disabled' : 'ui-label'} ${containerWidthClass} ${className}`.trim()}
> >
{label ? <span className={labelClass}>{label}</span> : null} {label ? <span className={labelClass}>{label}</span> : null}
<div className={inputWrapperClass}> <div className={inputWrapperClass}>

View File

@@ -28,7 +28,7 @@ export function SidebarNavItem({
onClick={onClick} onClick={onClick}
className={({ isActive }) => className={({ isActive }) =>
`inline-flex h-8 items-center rounded-lg text-sm font-medium transition ${layoutClass} ${ `inline-flex h-8 items-center rounded-lg text-sm font-medium transition ${layoutClass} ${
isActive ? 'bg-accent-500 text-white' : 'ui-body-secondary hover:bg-zinc-500/15' isActive ? 'ui-accent-active' : 'ui-body-secondary hover:bg-zinc-500/15'
}` }`
} }
> >

View File

@@ -1,6 +1,12 @@
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
:root { :root {
/* Consumer projects can override these accent tokens after importing @panic/web-ui styles. */
--accent-300: 168 155 191;
--accent-400: 149 135 173;
--accent-500: 125 111 152;
--accent-600: 106 93 132;
--accent-contrast: 255 255 255;
--bg-page: #16121a; --bg-page: #16121a;
--surface-bg: rgba(24, 24, 27, 0.45); --surface-bg: rgba(24, 24, 27, 0.45);
--surface-bg-strong: rgba(24, 24, 27, 0.62); --surface-bg-strong: rgba(24, 24, 27, 0.62);
@@ -16,6 +22,8 @@
--field-disabled-border: #3f3f46; --field-disabled-border: #3f3f46;
--field-disabled-text: #bbb6c3; --field-disabled-text: #bbb6c3;
--field-disabled-placeholder: #71717a; --field-disabled-placeholder: #71717a;
--field-selection-bg: rgb(var(--accent-500) / 0.42);
--field-selection-text: var(--text-primary);
--ghost-bg: rgba(24, 24, 27, 0.5); --ghost-bg: rgba(24, 24, 27, 0.5);
--ghost-border: #3f3f46; --ghost-border: #3f3f46;
--ghost-hover: rgba(39, 39, 42, 0.7); --ghost-hover: rgba(39, 39, 42, 0.7);
@@ -33,8 +41,8 @@
--error-border: rgba(252, 165, 165, 0.3); --error-border: rgba(252, 165, 165, 0.3);
--error-bg: rgba(239, 68, 68, 0.1); --error-bg: rgba(239, 68, 68, 0.1);
--error-text: #fecaca; --error-text: #fecaca;
--mdx-link: #7d6f98; --mdx-link: rgb(var(--accent-500));
--mdx-link-hover: #9587ad; --mdx-link-hover: rgb(var(--accent-400));
--mdx-inline-code-bg: #27272a; --mdx-inline-code-bg: #27272a;
--mdx-inline-code-border: #3f3f46; --mdx-inline-code-border: #3f3f46;
--mdx-codeblock-bg: #18181b; --mdx-codeblock-bg: #18181b;
@@ -42,8 +50,8 @@
--mdx-codeblock-text: #e4e4e7; --mdx-codeblock-text: #e4e4e7;
--mdx-codeblock-gutter: #a1a1aa; --mdx-codeblock-gutter: #a1a1aa;
--mdx-codeblock-active: #27272a; --mdx-codeblock-active: #27272a;
--mdx-codeblock-selection: rgba(125, 111, 152, 0.35); --mdx-codeblock-selection: rgb(var(--accent-500) / 0.35);
--mdx-codeblock-bracket: rgba(125, 111, 152, 0.45); --mdx-codeblock-bracket: rgb(var(--accent-500) / 0.45);
--shadow-glow: 0 0 0 1px rgba(63, 63, 70, 0.65), 0 18px 44px rgba(0, 0, 0, 0.45); --shadow-glow: 0 0 0 1px rgba(63, 63, 70, 0.65), 0 18px 44px rgba(0, 0, 0, 0.45);
} }
@@ -63,6 +71,8 @@
--field-disabled-border: #d7d7d7; --field-disabled-border: #d7d7d7;
--field-disabled-text: #71717a; --field-disabled-text: #71717a;
--field-disabled-placeholder: #a1a1aa; --field-disabled-placeholder: #a1a1aa;
--field-selection-bg: rgb(var(--accent-500) / 0.24);
--field-selection-text: var(--text-primary);
--ghost-bg: rgba(255, 255, 255, 0.88); --ghost-bg: rgba(255, 255, 255, 0.88);
--ghost-border: #d4d4d8; --ghost-border: #d4d4d8;
--ghost-hover: #f4f4f5; --ghost-hover: #f4f4f5;
@@ -78,8 +88,8 @@
--error-border: rgba(248, 113, 113, 0.35); --error-border: rgba(248, 113, 113, 0.35);
--error-bg: rgba(254, 226, 226, 0.8); --error-bg: rgba(254, 226, 226, 0.8);
--error-text: #991b1b; --error-text: #991b1b;
--mdx-link: #7d6f98; --mdx-link: rgb(var(--accent-500));
--mdx-link-hover: #6a5d84; --mdx-link-hover: rgb(var(--accent-600));
--mdx-inline-code-bg: #f4f4f5; --mdx-inline-code-bg: #f4f4f5;
--mdx-inline-code-border: #d4d4d8; --mdx-inline-code-border: #d4d4d8;
--mdx-codeblock-bg: #ffffff; --mdx-codeblock-bg: #ffffff;
@@ -87,7 +97,7 @@
--mdx-codeblock-text: #18181b; --mdx-codeblock-text: #18181b;
--mdx-codeblock-gutter: #71717a; --mdx-codeblock-gutter: #71717a;
--mdx-codeblock-active: #f4f4f5; --mdx-codeblock-active: #f4f4f5;
--mdx-codeblock-selection: rgba(125, 111, 152, 0.22); --mdx-codeblock-selection: rgb(var(--accent-500) / 0.22);
--mdx-codeblock-bracket: rgba(125, 111, 152, 0.32); --mdx-codeblock-bracket: rgb(var(--accent-500) / 0.32);
--shadow-glow: 0 0 0 1px rgba(212, 212, 216, 0.9), 0 18px 36px rgba(15, 23, 42, 0.08); --shadow-glow: 0 0 0 1px rgba(212, 212, 216, 0.9), 0 18px 36px rgba(15, 23, 42, 0.08);
} }

View File

@@ -12,13 +12,98 @@
appearance: none; appearance: none;
-webkit-appearance: none; -webkit-appearance: none;
-webkit-text-fill-color: var(--text-primary); -webkit-text-fill-color: var(--text-primary);
@apply w-full rounded-xl px-3 py-2 text-sm outline-none transition focus:border-accent-400 focus:ring-2 focus:ring-accent-400/30; @apply w-full rounded-xl px-3 py-2 text-sm outline-none transition;
}
.field:focus {
border-color: rgb(var(--accent-400));
box-shadow: 0 0 0 2px rgb(var(--accent-400) / 0.3);
} }
.field::placeholder { .field::placeholder {
color: var(--text-soft); color: var(--text-soft);
} }
.field::selection {
background-color: var(--field-selection-bg);
color: var(--field-selection-text);
-webkit-text-fill-color: var(--field-selection-text);
}
.field[type='date']::-webkit-datetime-edit-day-field,
.field[type='date']::-webkit-datetime-edit-month-field,
.field[type='date']::-webkit-datetime-edit-year-field,
.field[type='time']::-webkit-datetime-edit-hour-field,
.field[type='time']::-webkit-datetime-edit-minute-field,
.field[type='datetime-local']::-webkit-datetime-edit-day-field,
.field[type='datetime-local']::-webkit-datetime-edit-month-field,
.field[type='datetime-local']::-webkit-datetime-edit-year-field,
.field[type='datetime-local']::-webkit-datetime-edit-hour-field,
.field[type='datetime-local']::-webkit-datetime-edit-minute-field {
border-radius: 0.375rem;
}
.field[type='date']::-webkit-datetime-edit-day-field:focus {
border-radius: 0.375rem;
background-color: var(--field-selection-bg) !important;
color: var(--field-selection-text) !important;
-webkit-text-fill-color: var(--field-selection-text) !important;
}
.field[type='date']::-webkit-datetime-edit-month-field:focus {
border-radius: 0.375rem;
background-color: var(--field-selection-bg) !important;
color: var(--field-selection-text) !important;
-webkit-text-fill-color: var(--field-selection-text) !important;
}
.field[type='date']::-webkit-datetime-edit-year-field:focus {
border-radius: 0.375rem;
background-color: var(--field-selection-bg) !important;
color: var(--field-selection-text) !important;
-webkit-text-fill-color: var(--field-selection-text) !important;
}
.field[type='time']::-webkit-datetime-edit-hour-field:focus {
border-radius: 0.375rem;
background-color: var(--field-selection-bg) !important;
color: var(--field-selection-text) !important;
-webkit-text-fill-color: var(--field-selection-text) !important;
}
.field[type='time']::-webkit-datetime-edit-minute-field:focus {
border-radius: 0.375rem;
background-color: var(--field-selection-bg) !important;
color: var(--field-selection-text) !important;
-webkit-text-fill-color: var(--field-selection-text) !important;
}
.field[type='datetime-local']::-webkit-datetime-edit-day-field:focus {
border-radius: 0.375rem;
background-color: var(--field-selection-bg) !important;
color: var(--field-selection-text) !important;
-webkit-text-fill-color: var(--field-selection-text) !important;
}
.field[type='datetime-local']::-webkit-datetime-edit-month-field:focus {
border-radius: 0.375rem;
background-color: var(--field-selection-bg) !important;
color: var(--field-selection-text) !important;
-webkit-text-fill-color: var(--field-selection-text) !important;
}
.field[type='datetime-local']::-webkit-datetime-edit-year-field:focus {
border-radius: 0.375rem;
background-color: var(--field-selection-bg) !important;
color: var(--field-selection-text) !important;
-webkit-text-fill-color: var(--field-selection-text) !important;
}
.field[type='datetime-local']::-webkit-datetime-edit-hour-field:focus {
border-radius: 0.375rem;
background-color: var(--field-selection-bg) !important;
color: var(--field-selection-text) !important;
-webkit-text-fill-color: var(--field-selection-text) !important;
}
.field[type='datetime-local']::-webkit-datetime-edit-minute-field:focus {
border-radius: 0.375rem;
background-color: var(--field-selection-bg) !important;
color: var(--field-selection-text) !important;
-webkit-text-fill-color: var(--field-selection-text) !important;
}
.field:disabled { .field:disabled {
border-color: var(--field-disabled-border); border-color: var(--field-disabled-border);
background-color: var(--field-disabled-bg); background-color: var(--field-disabled-bg);
@@ -55,7 +140,13 @@
} }
.btn-solid.btn-primary { .btn-solid.btn-primary {
@apply bg-accent-500 text-white hover:bg-accent-400 disabled:opacity-100; background-color: rgb(var(--accent-500));
color: rgb(var(--accent-contrast));
@apply disabled:opacity-100;
}
.btn-solid.btn-primary:hover {
background-color: rgb(var(--accent-400));
} }
.btn-solid.btn-primary:disabled { .btn-solid.btn-primary:disabled {
@@ -107,16 +198,19 @@
} }
.btn-outlined.btn-primary { .btn-outlined.btn-primary {
@apply border-accent-500 text-accent-300; border-color: rgb(var(--accent-500));
color: rgb(var(--accent-300));
background-color: transparent; background-color: transparent;
} }
.btn-outlined.btn-primary:hover { .btn-outlined.btn-primary:hover {
@apply bg-accent-500/15 text-accent-300; background-color: rgb(var(--accent-500) / 0.15);
color: rgb(var(--accent-300));
} }
.btn-outlined.btn-primary:disabled { .btn-outlined.btn-primary:disabled {
@apply border-accent-500/40 text-accent-300/60; border-color: rgb(var(--accent-500) / 0.4);
color: rgb(var(--accent-300) / 0.6);
background-color: transparent; background-color: transparent;
} }
@@ -149,16 +243,17 @@
} }
.btn-noborder.btn-primary { .btn-noborder.btn-primary {
@apply text-accent-300; color: rgb(var(--accent-300));
background-color: transparent; background-color: transparent;
} }
.btn-noborder.btn-primary:hover { .btn-noborder.btn-primary:hover {
@apply bg-accent-500/15 text-accent-300; background-color: rgb(var(--accent-500) / 0.15);
color: rgb(var(--accent-300));
} }
.btn-noborder.btn-primary:disabled { .btn-noborder.btn-primary:disabled {
@apply text-accent-300/60; color: rgb(var(--accent-300) / 0.6);
background-color: transparent; background-color: transparent;
} }
@@ -228,6 +323,15 @@
color: var(--error-text); color: var(--error-text);
} }
.ui-accent-active {
background-color: rgb(var(--accent-500));
color: rgb(var(--accent-contrast));
}
.ui-accent-active:hover {
background-color: rgb(var(--accent-400));
}
.chip-root { .chip-root {
@apply inline-flex items-center rounded-full border px-2.5 py-1 text-xs font-semibold leading-none; @apply inline-flex items-center rounded-full border px-2.5 py-1 text-xs font-semibold leading-none;
} }