shadcn-svelte
Installation
Section titled “Installation”npm i @sjsf/shadcn4-theme
yarn add @sjsf/shadcn4-theme
pnpm add @sjsf/shadcn4-theme
bun add @sjsf/shadcn4-theme
bits-ui ^2.5.0
and @internationalized/date
^3.8.1
may be required.
Install shadcn-svelte
Section titled “Install shadcn-svelte”Installation - shadcn-svelte
Configuration
Section titled “Configuration”Register the theme source path by adding the following line to the app.css
file:.
@source "../node_modules/@sjsf/shadcn4-theme/dist";
Components
Section titled “Components”Since shadcn-svelte
is not a component library you should provide your components via setThemeContext
.
import { setThemeContext } from '@sjsf/shadcn4-theme';import * as components from '@sjsf/shadcn4-theme/new-york';
setThemeContext({ components })
Extra widgets
Section titled “Extra widgets”You can connect extra widgets using the following include
imports:
// Used by default in the following fields: multiEnumFieldimport "@sjsf/shadcn4-theme/extra-widgets/checkboxes-include"import "@sjsf/shadcn4-theme/extra-widgets/combobox-include"import "@sjsf/shadcn4-theme/extra-widgets/date-picker-include"// Used by default in the following fields: fileField, filesFieldimport "@sjsf/shadcn4-theme/extra-widgets/file-include"import "@sjsf/shadcn4-theme/extra-widgets/multi-select-include"import "@sjsf/shadcn4-theme/extra-widgets/radio-buttons-include"import "@sjsf/shadcn4-theme/extra-widgets/radio-include"import "@sjsf/shadcn4-theme/extra-widgets/range-include"import "@sjsf/shadcn4-theme/extra-widgets/switch-include"import "@sjsf/shadcn4-theme/extra-widgets/textarea-include"
UI options
Section titled “UI options”import type { ComponentProps } from "svelte";import type { HTMLAttributes, HTMLFormAttributes, HTMLInputAttributes, HTMLInputTypeAttribute, HTMLTextareaAttributes,} from "svelte/elements";import type { CalendarSingleRootProps, CheckboxRootProps, LabelRootProps, RadioGroupItemProps, RadioGroupRootProps, SelectMultipleRootProps, SelectSingleRootProps, SelectTriggerProps, SliderSingleRootProps, SwitchRootProps, WithElementRef, WithoutChildrenOrChild, CommandInputProps, SingleToggleGroupRootPropsWithoutHTML, BitsPrimitiveDivAttributes, Without, ToggleGroupRootPropsWithoutHTML, ToggleGroupItemProps,} from "bits-ui";import type { ButtonType, LayoutType } from "@sjsf/form/fields/components";import type { Button } from "@sjsf/shadcn4-theme/new-york";
type InputType = Exclude<HTMLInputTypeAttribute, "file">;
type InputProps = WithElementRef< Omit<HTMLInputAttributes, "type"> & ( | { type: "file"; files?: FileList } | { type?: InputType; files?: undefined } )>;
type ToggleVariants = { variant?: "default" | "outline" | undefined; size?: "default" | "sm" | "lg" | undefined;};
type ToggleGroupProps = SingleToggleGroupRootPropsWithoutHTML & Without<BitsPrimitiveDivAttributes, ToggleGroupRootPropsWithoutHTML> & ToggleVariants;
export interface UiOptions { shadcn4Button?: ComponentProps<typeof Button>; shadcn4Buttons?: { [B in ButtonType]: ComponentProps<typeof Button>; }; /** * Overrides the attributes of the description. */ descriptionAttributes?: HTMLAttributes<HTMLDivElement>; /** * Overrides the attributes of the errors list. */ errorsList?: HTMLAttributes<HTMLUListElement>;
form?: HTMLFormAttributes; /** * Overrides the attributes of the help. */ helpAttributes?: HTMLAttributes<HTMLDivElement>;
shadcn4Label?: LabelRootProps; /** * Overrides the attributes of any layout component. */ layout?: HTMLAttributes<HTMLDivElement>; /** * Overrides the attributes of a layout with a specific type. * This override takes precedence over the `layout` override, but does not replace it. */ layouts?: { [L in LayoutType]?: HTMLAttributes<HTMLDivElement>; }; shadcn4SubmitButton?: ComponentProps<typeof Button>; /** * Overrides the attributes of the field title */ titleAttributes?: HTMLAttributes<HTMLDivElement>;
shadcn4Checkbox?: WithoutChildrenOrChild<CheckboxRootProps>;
shadcn4Number?: InputProps;
shadcn4Select?: Omit<SelectSingleRootProps, "type">; shadcn4SelectTrigger?: SelectTriggerProps;
shadcn4Text?: InputProps;
shadcn4Checkboxes?: WithoutChildrenOrChild<CheckboxRootProps>;
shadcn4ComboboxTrigger?: ComponentProps<typeof Button>; shadcn4ComboboxInput?: CommandInputProps; shadcn4ComboboxEmptyText?: string;
shadcn4DatePicker?: Omit< WithoutChildrenOrChild<CalendarSingleRootProps>, "type" >; shadcn4DatePickerTrigger?: ComponentProps<typeof Button>; shadcn4DateFormatter?: (date: Date) => string;
file?: HTMLInputAttributes;
shadcn4MultiSelect?: Omit<SelectMultipleRootProps, "type">; shadcn4MultiSelectTrigger?: SelectTriggerProps;
shadcn4RadioButtons?: ToggleGroupProps; shadcn4RadioButtonsItem?: ToggleGroupItemProps & ToggleVariants;
shadcn4RadioGroup?: WithoutChildrenOrChild<RadioGroupRootProps>; shadcn4RadioItem?: Omit<WithoutChildrenOrChild<RadioGroupItemProps>, "value">;
shadcn4Range?: Omit<WithoutChildrenOrChild<SliderSingleRootProps>, "type">;
shadcn4Switch?: WithoutChildrenOrChild<SwitchRootProps>;
textarea?: HTMLTextareaAttributes;}
Widgets demo
Section titled “Widgets demo”{ "type": "object", "properties": { "checkbox": { "type": "object", "properties": { "default": { "type": "boolean" }, "error": { "type": "boolean" } } }, "checkboxes": { "type": "object", "properties": { "default": { "type": "array", "items": { "type": "string", "enum": [ "foo", "bar", "fuzz", "qux" ] }, "uniqueItems": true }, "error": { "type": "array", "items": { "type": "string", "enum": [ "foo", "bar", "fuzz", "qux" ] }, "uniqueItems": true } } }, "file": { "type": "object", "properties": { "default": { "type": "string", "format": "data-url" }, "error": { "type": "string", "format": "data-url" } } }, "multiFile": { "type": "object", "properties": { "default": { "type": "array", "items": { "type": "string", "format": "data-url" } }, "error": { "type": "array", "items": { "type": "string", "format": "data-url" } } } }, "number": { "type": "object", "properties": { "default": { "type": "number" }, "error": { "type": "number" } } }, "select": { "type": "object", "properties": { "default": { "type": "string", "enum": [ "foo", "bar", "fuzz", "qux" ] }, "error": { "type": "string", "enum": [ "foo", "bar", "fuzz", "qux" ] } } }, "text": { "type": "object", "properties": { "default": { "type": "string" }, "error": { "type": "string" } } }, "combobox": { "type": "object", "properties": { "default": { "type": "string", "enum": [ "foo", "bar", "fuzz", "qux" ] }, "error": { "type": "string", "enum": [ "foo", "bar", "fuzz", "qux" ] } } }, "datePicker": { "type": "object", "properties": { "default": { "type": "string" }, "error": { "type": "string" } } }, "multiSelect": { "type": "object", "properties": { "default": { "type": "array", "items": { "type": "string", "enum": [ "foo", "bar", "fuzz", "qux" ] }, "uniqueItems": true }, "error": { "type": "array", "items": { "type": "string", "enum": [ "foo", "bar", "fuzz", "qux" ] }, "uniqueItems": true } } }, "radioButtons": { "type": "object", "properties": { "default": { "type": "string", "enum": [ "foo", "bar", "fuzz", "qux" ] }, "error": { "type": "string", "enum": [ "foo", "bar", "fuzz", "qux" ] } } }, "radio": { "type": "object", "properties": { "default": { "type": "string", "enum": [ "foo", "bar", "fuzz", "qux" ] }, "error": { "type": "string", "enum": [ "foo", "bar", "fuzz", "qux" ] } } }, "range": { "type": "object", "properties": { "default": { "type": "number" }, "error": { "type": "number" } } }, "switch": { "type": "object", "properties": { "default": { "type": "boolean" }, "error": { "type": "boolean" } } }, "textarea": { "type": "object", "properties": { "default": { "type": "string" }, "error": { "type": "string" } } } }}
{ "checkboxes": { "default": { "ui:components": { "arrayField": "multiEnumField" } }, "error": { "ui:components": { "arrayField": "multiEnumField" } } }, "file": { "default": { "ui:components": { "stringField": "fileField" } }, "error": { "ui:components": { "stringField": "fileField" } } }, "multiFile": { "default": { "ui:components": { "arrayField": "<function: anonymous>" } }, "error": { "ui:components": { "arrayField": "<function: anonymous>" } } }, "select": { "default": { "ui:components": { "stringField": "enumField" } }, "error": { "ui:components": { "stringField": "enumField" } } }, "combobox": { "default": { "ui:components": { "stringField": "enumField", "selectWidget": "comboboxWidget" }, "ui:options": { "useLabel": false } }, "error": { "ui:components": { "stringField": "enumField", "selectWidget": "comboboxWidget" }, "ui:options": { "useLabel": false } } }, "datePicker": { "default": { "ui:components": { "textWidget": "datePickerWidget" }, "ui:options": { "useLabel": false } }, "error": { "ui:components": { "textWidget": "datePickerWidget" }, "ui:options": { "useLabel": false } } }, "multiSelect": { "default": { "ui:components": { "arrayField": "multiEnumField", "checkboxesWidget": "multiSelectWidget" }, "ui:options": { "useLabel": true } }, "error": { "ui:components": { "arrayField": "multiEnumField", "checkboxesWidget": "multiSelectWidget" }, "ui:options": { "useLabel": true } } }, "radioButtons": { "default": { "ui:components": { "stringField": "enumField", "selectWidget": "radioButtonsWidget" }, "ui:options": { "useLabel": false } }, "error": { "ui:components": { "stringField": "enumField", "selectWidget": "radioButtonsWidget" }, "ui:options": { "useLabel": false } } }, "radio": { "default": { "ui:components": { "stringField": "enumField", "selectWidget": "radioWidget" }, "ui:options": { "useLabel": false } }, "error": { "ui:components": { "stringField": "enumField", "selectWidget": "radioWidget" }, "ui:options": { "useLabel": false } } }, "range": { "default": { "ui:components": { "numberWidget": "rangeWidget" }, "ui:options": { "useLabel": false } }, "error": { "ui:components": { "numberWidget": "rangeWidget" }, "ui:options": { "useLabel": false } } }, "switch": { "default": { "ui:components": { "checkboxWidget": "switchWidget" } }, "error": { "ui:components": { "checkboxWidget": "switchWidget" } } }, "textarea": { "default": { "ui:components": { "textWidget": "textareaWidget" } }, "error": { "ui:components": { "textWidget": "textareaWidget" } } }}