sheerly 0.0.1
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 +3 -0
- package/lib/accordion.css +1 -0
- package/lib/accordion.d.ts +6 -0
- package/lib/alert.css +1 -0
- package/lib/alert.d.ts +8 -0
- package/lib/avatar.css +1 -0
- package/lib/avatar.d.ts +13 -0
- package/lib/badge.css +1 -0
- package/lib/badge.d.ts +5 -0
- package/lib/breadcrumb.css +1 -0
- package/lib/breadcrumb.d.ts +8 -0
- package/lib/button.css +1 -0
- package/lib/button.d.ts +7 -0
- package/lib/card.css +1 -0
- package/lib/card.d.ts +14 -0
- package/lib/carousel.css +1 -0
- package/lib/carousel.d.ts +21 -0
- package/lib/checkbox.css +1 -0
- package/lib/checkbox.d.ts +3 -0
- package/lib/cn.d.ts +5 -0
- package/lib/dialog.css +1 -0
- package/lib/dialog.d.ts +15 -0
- package/lib/dropdown-menu.css +1 -0
- package/lib/dropdown-menu.d.ts +49 -0
- package/lib/hover-card.css +1 -0
- package/lib/hover-card.d.ts +7 -0
- package/lib/index.css +1 -0
- package/lib/index.d.ts +33 -0
- package/lib/index.js +652 -0
- package/lib/input.css +1 -0
- package/lib/input.d.ts +5 -0
- package/lib/kbd.css +1 -0
- package/lib/kbd.d.ts +5 -0
- package/lib/label.css +1 -0
- package/lib/label.d.ts +5 -0
- package/lib/pagination.css +1 -0
- package/lib/pagination.d.ts +17 -0
- package/lib/popover.css +1 -0
- package/lib/popover.d.ts +7 -0
- package/lib/progress.css +1 -0
- package/lib/progress.d.ts +6 -0
- package/lib/radio.css +1 -0
- package/lib/radio.d.ts +5 -0
- package/lib/root.css +1 -0
- package/lib/select.css +1 -0
- package/lib/select.d.ts +10 -0
- package/lib/separator.css +1 -0
- package/lib/separator.d.ts +5 -0
- package/lib/sheet.css +1 -0
- package/lib/sheet.d.ts +16 -0
- package/lib/skeleton.css +1 -0
- package/lib/skeleton.d.ts +3 -0
- package/lib/slider.css +1 -0
- package/lib/slider.d.ts +3 -0
- package/lib/spinner.css +1 -0
- package/lib/spinner.d.ts +10 -0
- package/lib/switch.css +1 -0
- package/lib/switch.d.ts +5 -0
- package/lib/table.css +1 -0
- package/lib/table.d.ts +5 -0
- package/lib/tabs.css +1 -0
- package/lib/tabs.d.ts +13 -0
- package/lib/textarea.css +1 -0
- package/lib/textarea.d.ts +3 -0
- package/lib/toggle.css +1 -0
- package/lib/toggle.d.ts +16 -0
- package/lib/tooltip.css +1 -0
- package/lib/tooltip.d.ts +7 -0
- package/lib/typography.css +1 -0
- package/lib/typography.d.ts +9 -0
- package/package.json +33 -0
- package/src/accordion.css +108 -0
- package/src/accordion.tsx +15 -0
- package/src/alert.css +126 -0
- package/src/alert.tsx +25 -0
- package/src/avatar.css +75 -0
- package/src/avatar.tsx +30 -0
- package/src/badge.css +71 -0
- package/src/badge.tsx +19 -0
- package/src/breadcrumb.css +166 -0
- package/src/breadcrumb.tsx +71 -0
- package/src/button.css +214 -0
- package/src/button.tsx +30 -0
- package/src/card.css +99 -0
- package/src/card.tsx +41 -0
- package/src/carousel.css +183 -0
- package/src/carousel.tsx +30 -0
- package/src/checkbox.css +56 -0
- package/src/checkbox.tsx +10 -0
- package/src/cn.ts +7 -0
- package/src/dialog.css +175 -0
- package/src/dialog.tsx +47 -0
- package/src/dropdown-menu.css +257 -0
- package/src/dropdown-menu.tsx +88 -0
- package/src/hover-card.css +75 -0
- package/src/hover-card.tsx +16 -0
- package/src/index.css +33 -0
- package/src/index.ts +37 -0
- package/src/input.css +62 -0
- package/src/input.tsx +10 -0
- package/src/kbd.css +32 -0
- package/src/kbd.tsx +14 -0
- package/src/label.css +17 -0
- package/src/label.tsx +10 -0
- package/src/pagination.css +150 -0
- package/src/pagination.tsx +95 -0
- package/src/popover.css +65 -0
- package/src/popover.tsx +16 -0
- package/src/progress.css +79 -0
- package/src/progress.tsx +19 -0
- package/src/radio.css +61 -0
- package/src/radio.tsx +14 -0
- package/src/root.css +78 -0
- package/src/select.css +164 -0
- package/src/select.tsx +22 -0
- package/src/separator.css +14 -0
- package/src/separator.tsx +10 -0
- package/src/sheet.css +225 -0
- package/src/sheet.tsx +48 -0
- package/src/skeleton.css +15 -0
- package/src/skeleton.tsx +8 -0
- package/src/slider.css +68 -0
- package/src/slider.tsx +8 -0
- package/src/spinner.css +43 -0
- package/src/spinner.tsx +24 -0
- package/src/switch.css +79 -0
- package/src/switch.tsx +18 -0
- package/src/table.css +77 -0
- package/src/table.tsx +14 -0
- package/src/tabs.css +110 -0
- package/src/tabs.tsx +38 -0
- package/src/textarea.css +38 -0
- package/src/textarea.tsx +8 -0
- package/src/toggle.css +148 -0
- package/src/toggle.tsx +47 -0
- package/src/tooltip.css +60 -0
- package/src/tooltip.tsx +16 -0
- package/src/types.d.ts +42 -0
- package/src/typography.css +176 -0
- package/src/typography.tsx +13 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AnchorHTMLAttributes, HTMLAttributes } from 'react';
|
|
2
|
+
export declare function Pagination({ className, ...props }: HTMLAttributes<HTMLElement>): import("react").JSX.Element;
|
|
3
|
+
export declare function PaginationContent({ className, ...props }: HTMLAttributes<HTMLUListElement>): import("react").JSX.Element;
|
|
4
|
+
export declare function PaginationItem({ className, ...props }: HTMLAttributes<HTMLLIElement>): import("react").JSX.Element;
|
|
5
|
+
export interface PaginationLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
6
|
+
/** Marks the current page (renders like the outline button). */
|
|
7
|
+
isActive?: boolean;
|
|
8
|
+
'data-role'?: 'previous' | 'next';
|
|
9
|
+
}
|
|
10
|
+
export declare function PaginationLink({ className, isActive, ...props }: PaginationLinkProps): import("react").JSX.Element;
|
|
11
|
+
export declare function PaginationPrevious({ className, text, children, ...props }: PaginationLinkProps & {
|
|
12
|
+
text?: string;
|
|
13
|
+
}): import("react").JSX.Element;
|
|
14
|
+
export declare function PaginationNext({ className, text, children, ...props }: PaginationLinkProps & {
|
|
15
|
+
text?: string;
|
|
16
|
+
}): import("react").JSX.Element;
|
|
17
|
+
export declare function PaginationEllipsis({ className, ...props }: HTMLAttributes<HTMLSpanElement>): import("react").JSX.Element;
|
package/lib/popover.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.sheerly-popover{anchor-name:--sheerly-pop;anchor-scope:--sheerly-pop;width:fit-content;display:inline-block}.sheerly-popover-content{position-anchor:--sheerly-pop;position-area:var(--sheerly-popover-position,block-end);position-try-fallbacks:flip-block, flip-inline, flip-block flip-inline;position-visibility:anchors-visible;inset:unset;background-color:var(--sheerly-popover);color:var(--sheerly-popover-foreground);border:1px solid var(--sheerly-border);border-radius:var(--sheerly-radius-md);opacity:0;width:max-content;max-width:288px;transition:opacity .15s ease, display .15s allow-discrete, overlay .15s allow-discrete;margin:6px;padding:16px;font-family:Geist Sans,system-ui,-apple-system,sans-serif;font-size:14px;line-height:20px;position:fixed;overflow:auto;box-shadow:0 4px 16px -4px oklch(0% 0 0/.08),0 1px 2px oklch(0% 0 0/.04)}.sheerly-popover-content:popover-open{opacity:1}@starting-style{.sheerly-popover-content:popover-open{opacity:0}}
|
package/lib/popover.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { HTMLAttributes } from 'react';
|
|
2
|
+
export type PopoverProps = HTMLAttributes<HTMLSpanElement>;
|
|
3
|
+
/** Wrapper carrying the anchor. Nest the trigger button + content inside. */
|
|
4
|
+
export declare function Popover({ className, ...props }: PopoverProps): import("react").JSX.Element;
|
|
5
|
+
export type PopoverContentProps = HTMLAttributes<HTMLDivElement>;
|
|
6
|
+
/** The floating panel. Give it `popover` and an `id` matched by the trigger's `commandfor`. */
|
|
7
|
+
export declare function PopoverContent({ className, ...props }: PopoverContentProps): import("react").JSX.Element;
|
package/lib/progress.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.sheerly-progress{appearance:none;border-radius:var(--sheerly-radius-full);background-color:var(--sheerly-border);border:none;width:100%;height:8px;overflow:hidden}.sheerly-progress::-webkit-progress-bar{background-color:var(--sheerly-border);border-radius:var(--sheerly-radius-full)}.sheerly-progress::-webkit-progress-value{background-color:var(--sheerly-foreground);border-radius:var(--sheerly-radius-full);transition:width .3s}.sheerly-progress:indeterminate::-webkit-progress-bar{background-color:var(--sheerly-border)}.sheerly-progress[data-variant=blue]::-webkit-progress-value{background-color:oklch(54.6% .245 262.88)}:is(.sheerly-progress[data-variant=green],.sheerly-progress[data-variant=success])::-webkit-progress-value{background-color:oklch(52.7% .154 150.07)}:is(.sheerly-progress[data-variant=red],.sheerly-progress[data-variant=error])::-webkit-progress-value{background-color:var(--sheerly-destructive)}:is(.sheerly-progress[data-variant=amber],.sheerly-progress[data-variant=warning])::-webkit-progress-value{background-color:oklch(66.6% .179 58.32)}.sheerly-progress[data-size=sm]{height:4px}.sheerly-progress[data-size=lg]{height:12px}.dark .sheerly-progress{background-color:var(--sheerly-border)}.dark .sheerly-progress::-webkit-progress-bar{background-color:var(--sheerly-border)}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { ProgressHTMLAttributes } from 'react';
|
|
2
|
+
export interface ProgressProps extends ProgressHTMLAttributes<HTMLProgressElement> {
|
|
3
|
+
'data-variant'?: 'default' | 'blue' | 'green' | 'success' | 'red' | 'error' | 'amber' | 'warning';
|
|
4
|
+
'data-size'?: 'sm' | 'default' | 'lg';
|
|
5
|
+
}
|
|
6
|
+
export declare function Progress({ className, ...props }: ProgressProps): import("react").JSX.Element;
|
package/lib/radio.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.sheerly-radio-group{gap:12px;display:grid}.sheerly-radio{border-radius:var(--sheerly-radius-full);border:1px solid var(--sheerly-input);background-color:var(--sheerly-background);cursor:pointer;appearance:none;outline:none;flex-shrink:0;place-content:center;width:16px;height:16px;transition:background-color .15s,border-color .15s;display:grid}.sheerly-radio:before{content:"";border-radius:var(--sheerly-radius-full);background-color:var(--sheerly-background);width:6px;height:6px;transition:transform .1s;transform:scale(0)}.sheerly-radio:hover{border-color:var(--sheerly-border)}.sheerly-radio:checked,.sheerly-radio[data-state=checked]{background-color:var(--sheerly-foreground);border-color:var(--sheerly-foreground)}:is(.sheerly-radio:checked,.sheerly-radio[data-state=checked]):before{transform:scale(1)}.sheerly-radio:focus-visible{border-color:var(--sheerly-ring);box-shadow:var(--sheerly-focus-ring)}.sheerly-radio:disabled{background-color:var(--sheerly-muted);border-color:var(--sheerly-border);cursor:not-allowed;opacity:.5}.sheerly-radio[aria-invalid=true]{border-color:var(--sheerly-destructive);box-shadow:0 0 0 3px oklch(from var(--sheerly-destructive) l c h / 20%)}
|
package/lib/radio.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { HTMLAttributes, InputHTMLAttributes } from 'react';
|
|
2
|
+
export type RadioGroupProps = HTMLAttributes<HTMLDivElement>;
|
|
3
|
+
export declare function RadioGroup({ className, ...props }: RadioGroupProps): import("react").JSX.Element;
|
|
4
|
+
export type RadioProps = Omit<InputHTMLAttributes<HTMLInputElement>, 'type'>;
|
|
5
|
+
export declare function Radio({ className, ...props }: RadioProps): import("react").JSX.Element;
|
package/lib/root.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{--sheerly-radius:.625rem;--sheerly-radius-sm:calc(var(--sheerly-radius) * .6);--sheerly-radius-md:calc(var(--sheerly-radius) * .8);--sheerly-radius-lg:var(--sheerly-radius);--sheerly-radius-xl:calc(var(--sheerly-radius) * 1.4);--sheerly-radius-2xl:calc(var(--sheerly-radius) * 1.8);--sheerly-background:oklch(100% 0 0);--sheerly-foreground:oklch(14.5% 0 0);--sheerly-card:oklch(100% 0 0);--sheerly-card-foreground:oklch(14.5% 0 0);--sheerly-popover:oklch(100% 0 0);--sheerly-popover-foreground:oklch(14.5% 0 0);--sheerly-primary:oklch(20.5% 0 0);--sheerly-primary-foreground:oklch(98.5% 0 0);--sheerly-secondary:oklch(97% 0 0);--sheerly-secondary-foreground:oklch(20.5% 0 0);--sheerly-muted:oklch(97% 0 0);--sheerly-muted-foreground:oklch(55.6% 0 0);--sheerly-accent:oklch(97% 0 0);--sheerly-accent-foreground:oklch(20.5% 0 0);--sheerly-destructive:oklch(57.7% .245 27.325);--sheerly-border:oklch(92.2% 0 0);--sheerly-input:oklch(92.2% 0 0);--sheerly-ring:oklch(70.8% 0 0);--sheerly-sidebar:oklch(98.5% 0 0);--sheerly-sidebar-foreground:oklch(14.5% 0 0);--sheerly-sidebar-primary:oklch(20.5% 0 0);--sheerly-sidebar-primary-foreground:oklch(98.5% 0 0);--sheerly-sidebar-accent:oklch(97% 0 0);--sheerly-sidebar-accent-foreground:oklch(20.5% 0 0);--sheerly-sidebar-border:oklch(92.2% 0 0);--sheerly-sidebar-ring:oklch(70.8% 0 0)}.dark{--sheerly-background:oklch(14.5% 0 0);--sheerly-foreground:oklch(98.5% 0 0);--sheerly-card:oklch(20.5% 0 0);--sheerly-card-foreground:oklch(98.5% 0 0);--sheerly-popover:oklch(20.5% 0 0);--sheerly-popover-foreground:oklch(98.5% 0 0);--sheerly-primary:oklch(92.2% 0 0);--sheerly-primary-foreground:oklch(20.5% 0 0);--sheerly-secondary:oklch(26.9% 0 0);--sheerly-secondary-foreground:oklch(98.5% 0 0);--sheerly-muted:oklch(26.9% 0 0);--sheerly-muted-foreground:oklch(70.8% 0 0);--sheerly-accent:oklch(26.9% 0 0);--sheerly-accent-foreground:oklch(98.5% 0 0);--sheerly-destructive:oklch(70.4% .191 22.216);--sheerly-border:oklch(100% 0 0/.1);--sheerly-input:oklch(100% 0 0/.15);--sheerly-ring:oklch(55.6% 0 0);--sheerly-sidebar:oklch(20.5% 0 0);--sheerly-sidebar-foreground:oklch(98.5% 0 0);--sheerly-sidebar-primary:oklch(48.8% .243 264.376);--sheerly-sidebar-primary-foreground:oklch(98.5% 0 0);--sheerly-sidebar-accent:oklch(26.9% 0 0);--sheerly-sidebar-accent-foreground:oklch(98.5% 0 0);--sheerly-sidebar-border:oklch(100% 0 0/.1);--sheerly-sidebar-ring:oklch(55.6% 0 0)}:root{--sheerly-radius-full:9999px;--sheerly-focus-ring:0 0 0 3px oklch(from var(--sheerly-ring) l c h / 50%)}
|
package/lib/select.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.sheerly-select{appearance:base-select}.sheerly-select::picker(select){appearance:base-select}.sheerly-select{border-radius:var(--sheerly-radius-lg);border:1px solid var(--sheerly-input);white-space:nowrap;width:fit-content;color:var(--sheerly-foreground);cursor:pointer;background-color:#0000;outline:none;align-items:center;gap:8px;height:32px;padding:0 12px;font-family:Geist Sans,system-ui,-apple-system,sans-serif;font-size:14px;font-weight:400;line-height:20px;transition:border-color .15s,box-shadow .15s;display:inline-flex}.sheerly-select:focus-visible{border-color:var(--sheerly-ring);box-shadow:var(--sheerly-focus-ring)}.sheerly-select:disabled{pointer-events:none;opacity:.5}.sheerly-select[aria-invalid=true]{border-color:var(--sheerly-destructive);box-shadow:0 0 0 3px oklch(from var(--sheerly-destructive) l c h / 20%)}.sheerly-select:invalid,.sheerly-select[data-placeholder]{color:var(--sheerly-muted-foreground)}.sheerly-select[data-size=sm]{height:32px}.sheerly-select[data-size=lg]{height:40px;font-size:16px}.sheerly-select::picker-icon{width:16px;height:16px;color:var(--sheerly-muted-foreground);content:"";background-color:currentColor;transition:rotate .2s;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") 50%/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") 50%/contain no-repeat}.sheerly-select:open::picker-icon{rotate:180deg}.sheerly-select selectedcontent{align-items:center;gap:8px;display:flex}.sheerly-select option[value=""]{color:var(--sheerly-muted-foreground)}.sheerly-select::picker(select){border:1px solid var(--sheerly-border);border-radius:var(--sheerly-radius-xl);background-color:var(--sheerly-popover);color:var(--sheerly-popover-foreground);opacity:0;max-height:256px;transition:all .2s allow-discrete;padding:4px;overflow-y:auto;box-shadow:0 4px 16px -4px oklch(0% 0 0/.08),0 1px 2px oklch(0% 0 0/.04)}.sheerly-select:open::picker(select){opacity:1}@starting-style{.sheerly-select:open::picker(select){opacity:0}}.sheerly-select option{border-radius:var(--sheerly-radius-md);cursor:default;-webkit-user-select:none;user-select:none;align-items:center;gap:8px;padding:6px 8px;font-size:14px;line-height:20px;transition:background-color .1s;display:flex}.sheerly-select option:hover,.sheerly-select option:focus{background-color:var(--sheerly-accent)}.sheerly-select option:checked{font-weight:500}.sheerly-select option:disabled{color:var(--sheerly-muted-foreground);pointer-events:none}.sheerly-select option::checkmark{color:var(--sheerly-foreground);order:1;margin-left:auto}.sheerly-select optgroup{padding:4px 0}.sheerly-select optgroup legend{color:var(--sheerly-muted-foreground);padding:4px 8px;font-size:12px;font-weight:500;line-height:16px}.sheerly-select optgroup+optgroup{border-top:1px solid var(--sheerly-border);margin-top:4px;padding-top:4px}
|
package/lib/select.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { SelectHTMLAttributes } from 'react';
|
|
2
|
+
export interface SelectProps extends SelectHTMLAttributes<HTMLSelectElement> {
|
|
3
|
+
'data-size'?: 'sm' | 'default' | 'lg';
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Uses the customizable-select API. Requires
|
|
7
|
+
* `<button><selectedcontent></selectedcontent></button>` as the first child,
|
|
8
|
+
* which this wrapper injects before the consumer's <option>s.
|
|
9
|
+
*/
|
|
10
|
+
export declare function Select({ className, children, ...props }: SelectProps): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.sheerly-separator{background-color:var(--sheerly-border);flex-shrink:0;width:100%;height:1px}.sheerly-separator[data-orientation=vertical]{width:1px;height:100%}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { HTMLAttributes } from 'react';
|
|
2
|
+
export interface SeparatorProps extends HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
'data-orientation'?: 'horizontal' | 'vertical';
|
|
4
|
+
}
|
|
5
|
+
export declare function Separator({ className, ...props }: SeparatorProps): import("react").JSX.Element;
|
package/lib/sheet.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.sheerly-sheet{z-index:50;background-color:var(--sheerly-background);color:var(--sheerly-foreground);box-shadow:0 0 0 1px oklch(from var(--sheerly-foreground) l c h / 10%);opacity:0;max-width:100vw;max-height:100dvh;transition:translate .3s cubic-bezier(.32, .72, 0, 1), opacity .3s ease, display .3s allow-discrete, overlay .3s allow-discrete;border:none;outline:none;flex-direction:column;gap:16px;margin:0;padding:0;font-size:14px;line-height:20px;display:none;position:fixed;overflow:hidden}.sheerly-sheet[open]{opacity:1;display:flex}.sheerly-sheet::backdrop{-webkit-backdrop-filter:blur(1px);backdrop-filter:blur(1px);opacity:0;transition:opacity .3s ease, overlay .3s allow-discrete, display .3s allow-discrete;background-color:oklch(0% 0 0/.1)}.sheerly-sheet[open]::backdrop{opacity:1}@starting-style{.sheerly-sheet[open]::backdrop{opacity:0}}.sheerly-sheet{width:100%;max-width:384px;height:100dvh;inset:0 0 0 auto;translate:100%}.sheerly-sheet[open]{translate:0}@starting-style{.sheerly-sheet[open]{translate:100%}}.sheerly-sheet[data-side=left]{width:100%;max-width:384px;height:100dvh;inset:0 auto 0 0;translate:-100%}.sheerly-sheet[data-side=left][open]{translate:0}@starting-style{.sheerly-sheet[data-side=left][open]{translate:-100%}}.sheerly-sheet[data-side=top]{width:100%;max-width:none;height:auto;inset:0 0 auto;translate:0 -100%}.sheerly-sheet[data-side=top][open]{translate:0}@starting-style{.sheerly-sheet[data-side=top][open]{translate:0 -100%}}.sheerly-sheet[data-side=bottom]{width:100%;max-width:none;height:auto;inset:auto 0 0;translate:0 100%}.sheerly-sheet[data-side=bottom][open]{translate:0}@starting-style{.sheerly-sheet[data-side=bottom][open]{translate:0 100%}}.sheerly-sheet-header{flex-direction:column;flex-shrink:0;gap:4px;padding:16px;display:flex}.sheerly-sheet-title{color:var(--sheerly-foreground);margin:0;padding-right:32px;font-family:Geist Sans,system-ui,-apple-system,sans-serif;font-size:16px;font-weight:500;line-height:1}.sheerly-sheet-description{color:var(--sheerly-muted-foreground);margin:0;font-family:Geist Sans,system-ui,-apple-system,sans-serif;font-size:14px;font-weight:400;line-height:20px}.sheerly-sheet-body{flex:1;padding:0 16px;overflow-y:auto}.sheerly-sheet-footer{flex-direction:column;flex-shrink:0;gap:8px;margin-top:auto;padding:16px;display:flex}.sheerly-sheet-footer>*{width:100%}.sheerly-sheet-close{border-radius:var(--sheerly-radius-md);width:28px;height:28px;color:var(--sheerly-muted-foreground);cursor:pointer;z-index:1;background-color:#0000;border:none;outline:none;justify-content:center;align-items:center;padding:0;transition:background-color .15s,color .15s;display:inline-flex;position:absolute;top:12px;right:16px}.sheerly-sheet-close:hover{background-color:var(--sheerly-muted);color:var(--sheerly-foreground)}.sheerly-sheet-close:focus-visible{border-color:var(--sheerly-ring);box-shadow:var(--sheerly-focus-ring)}.sheerly-sheet-close svg{width:16px;height:16px}.sheerly-sheet-close:empty:before{content:"";background-color:currentColor;width:16px;height:16px;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 6 6 18'/%3E%3Cpath d='m6 6 12 12'/%3E%3C/svg%3E") 50%/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 6 6 18'/%3E%3Cpath d='m6 6 12 12'/%3E%3C/svg%3E") 50%/contain no-repeat}
|
package/lib/sheet.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ButtonHTMLAttributes, DialogHTMLAttributes, HTMLAttributes } from 'react';
|
|
2
|
+
export interface SheetProps extends DialogHTMLAttributes<HTMLDialogElement> {
|
|
3
|
+
'data-side'?: 'right' | 'left' | 'top' | 'bottom';
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Native <dialog> that slides in from an edge. Open via invoker command
|
|
7
|
+
* (`command="show-modal"`) or `.showModal()`. Add `closedby="any"` for
|
|
8
|
+
* light-dismiss.
|
|
9
|
+
*/
|
|
10
|
+
export declare function Sheet({ className, ...props }: SheetProps): import("react").JSX.Element;
|
|
11
|
+
export declare function SheetHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>): import("react").JSX.Element;
|
|
12
|
+
export declare function SheetTitle({ className, ...props }: HTMLAttributes<HTMLHeadingElement>): import("react").JSX.Element;
|
|
13
|
+
export declare function SheetDescription({ className, ...props }: HTMLAttributes<HTMLParagraphElement>): import("react").JSX.Element;
|
|
14
|
+
export declare function SheetBody({ className, ...props }: HTMLAttributes<HTMLDivElement>): import("react").JSX.Element;
|
|
15
|
+
export declare function SheetFooter({ className, ...props }: HTMLAttributes<HTMLDivElement>): import("react").JSX.Element;
|
|
16
|
+
export declare function SheetClose({ className, type, ...props }: ButtonHTMLAttributes<HTMLButtonElement>): import("react").JSX.Element;
|
package/lib/skeleton.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.sheerly-skeleton{border-radius:var(--sheerly-radius-sm);background-color:var(--sheerly-muted);animation:2s cubic-bezier(.4,0,.6,1) infinite sheerly-pulse}@keyframes sheerly-pulse{0%,to{opacity:1}50%{opacity:.5}}
|
package/lib/slider.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.sheerly-slider{appearance:none;background-color:var(--sheerly-border);border-radius:var(--sheerly-radius-full);cursor:pointer;outline:none;width:100%;height:4px;margin:8px 0}.sheerly-slider::-webkit-slider-runnable-track{appearance:none;background-color:var(--sheerly-border);border-radius:var(--sheerly-radius-full);height:4px}.sheerly-slider::-webkit-slider-thumb{appearance:none;border:2px solid var(--sheerly-foreground);cursor:grab;background-color:#fff;border-radius:50%;width:16px;height:16px;margin-top:-6px;transition:transform .15s,box-shadow .15s;transform:scale(.85)}.sheerly-slider:active::-webkit-slider-thumb{cursor:grabbing;transform:scale(1)}.sheerly-slider:focus-visible::-webkit-slider-thumb{box-shadow:var(--sheerly-focus-ring);transform:scale(1)}.sheerly-slider:disabled{opacity:.5;cursor:not-allowed}.sheerly-slider:disabled::-webkit-slider-thumb{cursor:not-allowed;border-color:var(--sheerly-input)}.dark .sheerly-slider{background-color:var(--sheerly-border)}.dark .sheerly-slider::-webkit-slider-runnable-track{background-color:var(--sheerly-border)}.dark .sheerly-slider::-webkit-slider-thumb{background-color:var(--sheerly-foreground);border-color:var(--sheerly-foreground)}
|
package/lib/slider.d.ts
ADDED
package/lib/spinner.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.sheerly-spinner{background-color:currentColor;flex-shrink:0;width:16px;height:16px;animation:1s linear infinite sheerly-spin;display:inline-block;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 12a9 9 0 1 1-6.219-8.56'/%3E%3C/svg%3E") 50%/contain no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 12a9 9 0 1 1-6.219-8.56'/%3E%3C/svg%3E") 50%/contain no-repeat}.sheerly-spinner[data-size=sm]{width:12px;height:12px}.sheerly-spinner[data-size=md]{width:20px;height:20px}.sheerly-spinner[data-size=lg]{width:24px;height:24px}@keyframes sheerly-spin{0%{rotate:0deg}to{rotate:360deg}}
|
package/lib/spinner.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { HTMLAttributes } from 'react';
|
|
2
|
+
export interface SpinnerProps extends HTMLAttributes<HTMLSpanElement> {
|
|
3
|
+
'data-size'?: 'sm' | 'default' | 'md' | 'lg';
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Loading spinner. The glyph is embedded in CSS (masked ::before), so no SVG
|
|
7
|
+
* child is needed — this renders a bare <span>. It inherits the current text
|
|
8
|
+
* color. Pass an <svg> child if you prefer to ship your own icon.
|
|
9
|
+
*/
|
|
10
|
+
export declare function Spinner({ className, children, ...props }: SpinnerProps): import("react").JSX.Element;
|
package/lib/switch.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.sheerly-switch{border-radius:var(--sheerly-radius-full);cursor:pointer;appearance:none;background-color:var(--sheerly-input);border:none;outline:none;flex-shrink:0;align-items:center;width:32px;height:18px;transition:background-color .15s;display:inline-flex;position:relative}.sheerly-switch:before{content:"";border-radius:var(--sheerly-radius-full);background-color:var(--sheerly-background);pointer-events:none;width:14px;height:14px;transition:transform .15s;display:block;position:absolute;top:50%;left:2px;transform:translateY(-50%)}.sheerly-switch:hover{background-color:var(--sheerly-ring)}.sheerly-switch:checked,.sheerly-switch[data-state=checked]{background-color:var(--sheerly-foreground)}:is(.sheerly-switch:checked,.sheerly-switch[data-state=checked]):before{background-color:var(--sheerly-background);transform:translate(14px)translateY(-50%)}.sheerly-switch:focus-visible{box-shadow:var(--sheerly-focus-ring)}.sheerly-switch:disabled{background-color:var(--sheerly-muted);cursor:not-allowed}.sheerly-switch:disabled:before{background-color:var(--sheerly-input)}.sheerly-switch[data-size=sm]{width:24px;height:14px}.sheerly-switch[data-size=sm]:before{width:10px;height:10px}:is(.sheerly-switch[data-size=sm]:checked,.sheerly-switch[data-size=sm][data-state=checked]):before{transform:translate(10px)translateY(-50%)}
|
package/lib/switch.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { InputHTMLAttributes } from 'react';
|
|
2
|
+
export interface SwitchProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'role'> {
|
|
3
|
+
'data-size'?: 'default' | 'sm';
|
|
4
|
+
}
|
|
5
|
+
export declare function Switch({ className, ...props }: SwitchProps): import("react").JSX.Element;
|
package/lib/table.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.sheerly-table-container{width:100%;position:relative;overflow-x:auto}.sheerly-table{caption-side:bottom;border-collapse:collapse;width:100%;color:var(--sheerly-foreground);font-family:Geist Sans,system-ui,-apple-system,sans-serif;font-size:14px;line-height:20px}.sheerly-table caption{color:var(--sheerly-muted-foreground);margin-top:16px;font-size:14px;line-height:20px}.sheerly-table thead tr{border-bottom:1px solid var(--sheerly-border)}.sheerly-table th{text-align:left;vertical-align:middle;white-space:nowrap;height:40px;color:var(--sheerly-foreground);padding:0 8px;font-weight:500}.sheerly-table tbody tr{border-bottom:1px solid var(--sheerly-border);transition:background-color .1s}.sheerly-table tbody tr:last-child{border-bottom:none}.sheerly-table tbody tr:hover{background-color:var(--sheerly-accent)}.sheerly-table tbody tr[data-state=selected]{background-color:var(--sheerly-muted)}.sheerly-table td{vertical-align:middle;white-space:nowrap;padding:8px}.sheerly-table tfoot{border-top:1px solid var(--sheerly-border);background-color:var(--sheerly-accent);font-weight:500}.sheerly-table tfoot tr:last-child{border-bottom:none}.sheerly-table tfoot td,.sheerly-table tfoot th{vertical-align:middle;padding:8px}
|
package/lib/table.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { HTMLAttributes, TableHTMLAttributes } from 'react';
|
|
2
|
+
export type TableContainerProps = HTMLAttributes<HTMLDivElement>;
|
|
3
|
+
export declare function TableContainer({ className, ...props }: TableContainerProps): import("react").JSX.Element;
|
|
4
|
+
export type TableProps = TableHTMLAttributes<HTMLTableElement>;
|
|
5
|
+
export declare function Table({ className, ...props }: TableProps): import("react").JSX.Element;
|
package/lib/tabs.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.sheerly-tabs{flex-direction:column;gap:8px;display:flex}.sheerly-tabs-list{background-color:var(--sheerly-muted);border-radius:8px;justify-content:center;align-items:center;width:fit-content;height:36px;padding:3px;display:inline-flex}.sheerly-tabs-list[data-variant=line]{border-bottom:1px solid var(--sheerly-border);background-color:#0000;border-radius:0;gap:4px;height:auto;padding:0}.sheerly-tabs-trigger{white-space:nowrap;color:var(--sheerly-muted-foreground);cursor:pointer;background-color:#0000;border:1px solid #0000;border-radius:6px;outline:none;flex:1;justify-content:center;align-items:center;gap:6px;padding:4px 8px;font-family:Geist Sans,system-ui,-apple-system,sans-serif;font-size:14px;font-weight:500;line-height:20px;transition:color .15s,background-color .15s;display:inline-flex;position:relative}.sheerly-tabs-trigger:hover{color:var(--sheerly-foreground)}.sheerly-tabs-trigger:focus-visible{box-shadow:var(--sheerly-focus-ring)}.sheerly-tabs-trigger:disabled{pointer-events:none;opacity:.5}.sheerly-tabs-trigger[aria-selected=true],.sheerly-tabs-trigger[data-state=active]{background-color:var(--sheerly-background);color:var(--sheerly-foreground);box-shadow:0 1px 2px #0000000d}.sheerly-tabs-list[data-variant=line] .sheerly-tabs-trigger{box-shadow:none;border-radius:0;padding:8px 12px}.sheerly-tabs-list[data-variant=line] .sheerly-tabs-trigger[aria-selected=true],.sheerly-tabs-list[data-variant=line] .sheerly-tabs-trigger[data-state=active]{box-shadow:none;background-color:#0000}:is(.sheerly-tabs-list[data-variant=line] .sheerly-tabs-trigger[aria-selected=true],.sheerly-tabs-list[data-variant=line] .sheerly-tabs-trigger[data-state=active]):after{content:"";background-color:var(--sheerly-foreground);height:2px;position:absolute;bottom:-1px;left:0;right:0}.sheerly-tabs-trigger svg{pointer-events:none;flex-shrink:0;width:16px;height:16px}.sheerly-tabs-content{outline:none;flex:1}.sheerly-tabs-content[hidden]{display:none}
|
package/lib/tabs.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ButtonHTMLAttributes, HTMLAttributes } from 'react';
|
|
2
|
+
export type TabsProps = HTMLAttributes<HTMLDivElement>;
|
|
3
|
+
export declare function Tabs({ className, ...props }: TabsProps): import("react").JSX.Element;
|
|
4
|
+
export interface TabsListProps extends HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
'data-variant'?: 'line';
|
|
6
|
+
}
|
|
7
|
+
export declare function TabsList({ className, role, ...props }: TabsListProps): import("react").JSX.Element;
|
|
8
|
+
export interface TabsTriggerProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
9
|
+
'data-state'?: 'active';
|
|
10
|
+
}
|
|
11
|
+
export declare function TabsTrigger({ className, role, ...props }: TabsTriggerProps): import("react").JSX.Element;
|
|
12
|
+
export type TabsContentProps = HTMLAttributes<HTMLDivElement>;
|
|
13
|
+
export declare function TabsContent({ className, role, ...props }: TabsContentProps): import("react").JSX.Element;
|
package/lib/textarea.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.sheerly-textarea{border-radius:var(--sheerly-radius-lg);border:1px solid var(--sheerly-input);width:100%;min-height:64px;color:var(--sheerly-foreground);resize:vertical;field-sizing:content;background-color:#0000;outline:none;padding:6px 10px;font-family:Geist Sans,system-ui,-apple-system,sans-serif;font-size:14px;font-weight:400;line-height:20px;transition:border-color .15s,box-shadow .15s;display:block}.sheerly-textarea::placeholder{color:var(--sheerly-muted-foreground)}.sheerly-textarea:focus-visible{border-color:var(--sheerly-ring);box-shadow:var(--sheerly-focus-ring)}.sheerly-textarea:disabled{cursor:not-allowed;opacity:.5}.sheerly-textarea[aria-invalid=true]{border-color:var(--sheerly-destructive);box-shadow:0 0 0 3px oklch(from var(--sheerly-destructive) l c h / 20%)}
|
package/lib/toggle.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.sheerly-toggle{border-radius:var(--sheerly-radius-lg);white-space:nowrap;color:var(--sheerly-foreground);cursor:pointer;-webkit-user-select:none;user-select:none;background-color:#0000;border:1px solid #0000;outline:none;justify-content:center;align-items:center;gap:4px;min-width:32px;height:32px;padding:0 10px;font-family:Geist Sans,system-ui,-apple-system,sans-serif;font-size:14px;font-weight:500;line-height:20px;transition:all .15s;display:inline-flex}.sheerly-toggle>input[type=checkbox]{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.sheerly-toggle:hover{background-color:var(--sheerly-muted);color:var(--sheerly-foreground)}.sheerly-toggle:focus-visible{border-color:var(--sheerly-ring);box-shadow:var(--sheerly-focus-ring)}.sheerly-toggle:has(>input:focus-visible){border-color:var(--sheerly-ring);box-shadow:var(--sheerly-focus-ring)}.sheerly-toggle:disabled{pointer-events:none;opacity:.5}.sheerly-toggle:has(>input:disabled){pointer-events:none;opacity:.5}.sheerly-toggle[aria-invalid=true]{border-color:var(--sheerly-destructive);box-shadow:0 0 0 3px oklch(from var(--sheerly-destructive) l c h / 20%)}.sheerly-toggle[aria-pressed=true],.sheerly-toggle[data-state=on]{background-color:var(--sheerly-muted)}.sheerly-toggle:has(>input:checked){background-color:var(--sheerly-muted)}.sheerly-toggle[data-variant=default]{background-color:#0000}.sheerly-toggle[data-variant=outline]{border-color:var(--sheerly-input);background-color:#0000}.sheerly-toggle[data-variant=outline]:hover{background-color:var(--sheerly-muted)}.sheerly-toggle[data-size=default]{min-width:32px;height:32px;padding:0 10px}.sheerly-toggle[data-size=sm]{border-radius:min(var(--sheerly-radius-md), 12px);min-width:28px;height:28px;padding:0 10px;font-size:12.8px}.sheerly-toggle[data-size=sm] svg{width:14px;height:14px}.sheerly-toggle[data-size=lg]{min-width:36px;height:36px;padding:0 10px}.sheerly-toggle:has([data-icon=inline-start]){padding-inline-start:8px}.sheerly-toggle:has([data-icon=inline-end]){padding-inline-end:8px}.sheerly-toggle[data-size=sm]:has([data-icon=inline-start]){padding-inline-start:6px}.sheerly-toggle[data-size=sm]:has([data-icon=inline-end]){padding-inline-end:6px}.sheerly-toggle svg{pointer-events:none;flex-shrink:0;width:16px;height:16px}
|
package/lib/toggle.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { LabelHTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
export interface ToggleProps extends Omit<LabelHTMLAttributes<HTMLLabelElement>, 'onChange'> {
|
|
3
|
+
'data-variant'?: 'default' | 'outline';
|
|
4
|
+
'data-size'?: 'sm' | 'default' | 'lg';
|
|
5
|
+
/** Controlled pressed state (drives the nested checkbox). */
|
|
6
|
+
pressed?: boolean;
|
|
7
|
+
/** Uncontrolled initial pressed state. */
|
|
8
|
+
defaultPressed?: boolean;
|
|
9
|
+
/** Fires with the next pressed state when toggled. */
|
|
10
|
+
onPressedChange?: (pressed: boolean) => void;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
name?: string;
|
|
13
|
+
value?: string;
|
|
14
|
+
children?: ReactNode;
|
|
15
|
+
}
|
|
16
|
+
export declare function Toggle({ className, pressed, defaultPressed, onPressedChange, disabled, name, value, children, ...props }: ToggleProps): import("react").JSX.Element;
|
package/lib/tooltip.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.sheerly-tooltip{anchor-name:--sheerly-tip;anchor-scope:--sheerly-tip;width:fit-content;display:inline-block}.sheerly-tooltip-content{position-anchor:--sheerly-tip;position-area:var(--sheerly-tooltip-position,block-start);position-try-fallbacks:flip-block, flip-inline, flip-block flip-inline;position-visibility:anchors-visible;inset:unset;background-color:var(--sheerly-foreground);color:var(--sheerly-background);text-align:center;white-space:normal;text-wrap:pretty;border-radius:var(--sheerly-radius-sm);pointer-events:none;opacity:0;max-width:200px;transition:opacity .15s ease, display .15s allow-discrete, overlay .15s allow-discrete;border:none;margin:6px;padding:4px 8px;font-family:Geist Sans,system-ui,-apple-system,sans-serif;font-size:12px;font-weight:400;line-height:16px;position:fixed;overflow:visible}.sheerly-tooltip-content:popover-open{opacity:1}@starting-style{.sheerly-tooltip-content:popover-open{opacity:0}}
|
package/lib/tooltip.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { HTMLAttributes } from 'react';
|
|
2
|
+
export type TooltipProps = HTMLAttributes<HTMLSpanElement>;
|
|
3
|
+
/** Wrapper carrying the anchor. Nest the trigger + content inside. */
|
|
4
|
+
export declare function Tooltip({ className, ...props }: TooltipProps): import("react").JSX.Element;
|
|
5
|
+
export type TooltipContentProps = HTMLAttributes<HTMLSpanElement>;
|
|
6
|
+
/** The floating label. Give it `popover="hint"` and an `id` matched by the trigger's `interestfor`. */
|
|
7
|
+
export declare function TooltipContent({ className, ...props }: TooltipContentProps): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.sheerly-typography{color:var(--sheerly-foreground);font-family:Geist Sans,Geist,system-ui,-apple-system,sans-serif;font-size:16px;line-height:1.75}.sheerly-typography h1{letter-spacing:-.025em;text-wrap:balance;scroll-margin-block-start:5rem;font-size:36px;font-weight:800;line-height:1.1}.sheerly-typography h2{letter-spacing:-.025em;border-bottom:1px solid var(--sheerly-border);padding-bottom:8px;scroll-margin-block-start:5rem;font-size:30px;font-weight:600;line-height:1.2}.sheerly-typography h3{letter-spacing:-.025em;scroll-margin-block-start:5rem;font-size:24px;font-weight:600;line-height:1.3}.sheerly-typography h4{letter-spacing:-.025em;scroll-margin-block-start:5rem;font-size:20px;font-weight:600;line-height:1.4}.sheerly-typography h1,.sheerly-typography h2,.sheerly-typography h3,.sheerly-typography h4,.sheerly-typography p,.sheerly-typography blockquote,.sheerly-typography ul,.sheerly-typography ol,.sheerly-typography table,.sheerly-typography pre{margin-block-start:24px}.sheerly-typography h2{margin-block-start:40px}.sheerly-typography h3,.sheerly-typography h4{margin-block-start:32px}.sheerly-typography>:first-child{margin-block-start:0}.sheerly-typography a{color:var(--sheerly-primary);text-underline-offset:4px;font-weight:500;text-decoration:underline}.sheerly-typography a:hover{color:oklch(from var(--sheerly-primary) l c h / 80%)}.sheerly-typography blockquote{border-inline-start:2px solid var(--sheerly-border);color:var(--sheerly-muted-foreground);padding-inline-start:24px;font-style:italic}.sheerly-typography ul{padding-inline-start:24px;list-style:outside}.sheerly-typography ol{padding-inline-start:24px;list-style:decimal}.sheerly-typography li{margin-block-start:8px}.sheerly-typography li::marker{color:var(--sheerly-muted-foreground)}.sheerly-typography code{border-radius:var(--sheerly-radius-sm);background-color:var(--sheerly-muted);padding:.2em .35em;font-family:Geist Mono,ui-monospace,monospace;font-size:.875em;font-weight:600}.sheerly-typography pre{border-radius:var(--sheerly-radius-md);background-color:var(--sheerly-muted);padding:16px;overflow-x:auto}.sheerly-typography pre code{background-color:#0000;padding:0;font-weight:400}.sheerly-typography table{border-collapse:collapse;width:100%;font-size:14px}.sheerly-typography th,.sheerly-typography td{border:1px solid var(--sheerly-border);text-align:start;padding:8px 16px}.sheerly-typography th{font-weight:700}.sheerly-typography tbody tr:nth-child(2n){background-color:oklch(from var(--sheerly-muted) l c h / 50%)}.sheerly-typography small{font-size:14px;font-weight:500;line-height:1}.sheerly-typography [data-variant=lead]{color:var(--sheerly-muted-foreground);font-size:20px}.sheerly-typography [data-variant=large]{font-size:18px;font-weight:600}.sheerly-typography [data-variant=muted]{color:var(--sheerly-muted-foreground);font-size:14px}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { HTMLAttributes } from 'react';
|
|
2
|
+
export interface TypographyProps extends HTMLAttributes<HTMLDivElement> {
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* A prose wrapper. Unlike shadcn (per-element utility classes), Sheerly styles
|
|
6
|
+
* every child element (h1–h4, p, a, blockquote, ul/ol, li, code, table, …) via
|
|
7
|
+
* one `.sheerly-typography` class — just render semantic HTML inside it.
|
|
8
|
+
*/
|
|
9
|
+
export declare function Typography({ className, ...props }: TypographyProps): import("react").JSX.Element;
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sheerly",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "vite",
|
|
7
|
+
"build": "tsc -b && vite build",
|
|
8
|
+
"build:lib": "tsc -b && vite build --config vite.lib.config.ts",
|
|
9
|
+
"lint": "oxlint",
|
|
10
|
+
"preview": "vite preview"
|
|
11
|
+
},
|
|
12
|
+
"main": "lib/index.js",
|
|
13
|
+
"types": "lib/index.d.ts",
|
|
14
|
+
"files": [
|
|
15
|
+
"src",
|
|
16
|
+
"lib"
|
|
17
|
+
],
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@tailwindcss/vite": "^4.3.2",
|
|
20
|
+
"@types/node": "^26.1.1",
|
|
21
|
+
"@types/react": "^19.2.17",
|
|
22
|
+
"@types/react-dom": "^19.2.3",
|
|
23
|
+
"@vitejs/plugin-react": "^6.0.3",
|
|
24
|
+
"nuqs": "^2.9.0",
|
|
25
|
+
"oxlint": "^1.73.0",
|
|
26
|
+
"react": "^19.2.7",
|
|
27
|
+
"react-dom": "^19.2.7",
|
|
28
|
+
"tailwindcss": "^4.3.2",
|
|
29
|
+
"typescript": "^6.0.3",
|
|
30
|
+
"unplugin-dts": "^1.0.3",
|
|
31
|
+
"vite": "^8.1.4"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/* Accordion — native <details>; shared name attribute makes items exclusive */
|
|
2
|
+
.sheerly-accordion {
|
|
3
|
+
/* Enable animating height to/from the `auto` keyword. */
|
|
4
|
+
interpolate-size: allow-keywords;
|
|
5
|
+
|
|
6
|
+
/* Bottom border between items (shadcn: not-last:border-b) */
|
|
7
|
+
&:not(:last-of-type) {
|
|
8
|
+
border-bottom: 1px solid var(--sheerly-border);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/* Remove default marker */
|
|
12
|
+
& summary {
|
|
13
|
+
display: flex;
|
|
14
|
+
align-items: flex-start;
|
|
15
|
+
justify-content: space-between;
|
|
16
|
+
gap: 16px;
|
|
17
|
+
padding: 10px 0;
|
|
18
|
+
border: 1px solid transparent;
|
|
19
|
+
border-radius: var(--sheerly-radius-lg);
|
|
20
|
+
font-family: "Geist Sans", system-ui, -apple-system, sans-serif;
|
|
21
|
+
font-size: 14px;
|
|
22
|
+
font-weight: 500;
|
|
23
|
+
line-height: 20px;
|
|
24
|
+
color: var(--sheerly-foreground);
|
|
25
|
+
cursor: pointer;
|
|
26
|
+
list-style: none;
|
|
27
|
+
outline: none;
|
|
28
|
+
transition: box-shadow 0.15s ease, border-color 0.15s ease;
|
|
29
|
+
|
|
30
|
+
&::-webkit-details-marker {
|
|
31
|
+
display: none;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&::marker {
|
|
35
|
+
content: "";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* Chevron icon (down when closed, flips to up when open) */
|
|
39
|
+
&::after {
|
|
40
|
+
content: "";
|
|
41
|
+
flex-shrink: 0;
|
|
42
|
+
width: 16px;
|
|
43
|
+
height: 16px;
|
|
44
|
+
background-color: var(--sheerly-muted-foreground);
|
|
45
|
+
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
|
|
46
|
+
mask-size: contain;
|
|
47
|
+
mask-repeat: no-repeat;
|
|
48
|
+
mask-position: center;
|
|
49
|
+
transition: rotate 0.2s ease;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
&:hover {
|
|
53
|
+
text-decoration: underline;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
&:focus-visible {
|
|
57
|
+
border-color: var(--sheerly-ring);
|
|
58
|
+
box-shadow: var(--sheerly-focus-ring);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
& .sheerly-accordion-content {
|
|
63
|
+
font-family: "Geist Sans", system-ui, -apple-system, sans-serif;
|
|
64
|
+
font-size: 14px;
|
|
65
|
+
font-weight: 400;
|
|
66
|
+
line-height: 20px;
|
|
67
|
+
color: var(--sheerly-muted-foreground);
|
|
68
|
+
padding-top: 0;
|
|
69
|
+
padding-bottom: 10px;
|
|
70
|
+
|
|
71
|
+
& a {
|
|
72
|
+
text-decoration: underline;
|
|
73
|
+
text-underline-offset: 3px;
|
|
74
|
+
|
|
75
|
+
&:hover {
|
|
76
|
+
color: var(--sheerly-foreground);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
& p:not(:last-child) {
|
|
81
|
+
margin-bottom: 16px;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* Animate the content wrapper open/closed. `interpolate-size` above lets
|
|
86
|
+
height interpolate to/from `auto`; `allow-discrete` handles the
|
|
87
|
+
content-visibility flip so the collapse animates too. */
|
|
88
|
+
&::details-content {
|
|
89
|
+
height: 0;
|
|
90
|
+
opacity: 0;
|
|
91
|
+
overflow: hidden;
|
|
92
|
+
transition:
|
|
93
|
+
height 0.2s ease,
|
|
94
|
+
content-visibility 0.2s ease,
|
|
95
|
+
opacity 0.2s ease;
|
|
96
|
+
transition-behavior: allow-discrete;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
&[open]::details-content {
|
|
100
|
+
height: auto;
|
|
101
|
+
opacity: 1;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/* Open state — rotate chevron */
|
|
105
|
+
&[open] > summary::after {
|
|
106
|
+
rotate: 180deg;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { DetailsHTMLAttributes, HTMLAttributes } from 'react'
|
|
2
|
+
import { cn } from './cn'
|
|
3
|
+
|
|
4
|
+
export type AccordionProps = DetailsHTMLAttributes<HTMLDetailsElement>
|
|
5
|
+
|
|
6
|
+
/** Native <details>. Set the same `name` on siblings for exclusive open. */
|
|
7
|
+
export function Accordion({ className, ...props }: AccordionProps) {
|
|
8
|
+
return <details className={cn('sheerly-accordion', className)} {...props} />
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type AccordionContentProps = HTMLAttributes<HTMLDivElement>
|
|
12
|
+
|
|
13
|
+
export function AccordionContent({ className, ...props }: AccordionContentProps) {
|
|
14
|
+
return <div className={cn('sheerly-accordion-content', className)} {...props} />
|
|
15
|
+
}
|
package/src/alert.css
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Alert — a callout for user attention. <div role="alert">
|
|
3
|
+
* The leading icon is embedded in CSS (via a masked ::before) and swaps
|
|
4
|
+
* per variant, so no <svg> child is required.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* <div class="sheerly-alert" role="alert">
|
|
8
|
+
* <div class="sheerly-alert-title">Payment successful</div>
|
|
9
|
+
* <div class="sheerly-alert-description">Your payment has been processed.</div>
|
|
10
|
+
* <div class="sheerly-alert-action"><button class="sheerly-button">Undo</button></div>
|
|
11
|
+
* </div>
|
|
12
|
+
*
|
|
13
|
+
* Variants (data-variant): default | destructive | success | info | warning
|
|
14
|
+
*/
|
|
15
|
+
.sheerly-alert {
|
|
16
|
+
position: relative;
|
|
17
|
+
display: grid;
|
|
18
|
+
grid-template-columns: auto 1fr;
|
|
19
|
+
column-gap: 8px;
|
|
20
|
+
row-gap: 2px;
|
|
21
|
+
width: 100%;
|
|
22
|
+
border: 1px solid transparent;
|
|
23
|
+
border-radius: var(--sheerly-radius-lg);
|
|
24
|
+
padding: 8px 10px;
|
|
25
|
+
background-color: var(--sheerly-card);
|
|
26
|
+
color: var(--sheerly-card-foreground);
|
|
27
|
+
box-shadow: 0 0 0 1px oklch(from var(--sheerly-foreground) l c h / 10%);
|
|
28
|
+
font-family: "Geist Sans", system-ui, -apple-system, sans-serif;
|
|
29
|
+
font-size: 14px;
|
|
30
|
+
line-height: 20px;
|
|
31
|
+
text-align: left;
|
|
32
|
+
|
|
33
|
+
/* Embedded leading icon (default: info) — spans both text rows. */
|
|
34
|
+
&::before {
|
|
35
|
+
content: "";
|
|
36
|
+
grid-row: 1 / span 2;
|
|
37
|
+
align-self: start;
|
|
38
|
+
translate: 0 2px;
|
|
39
|
+
width: 16px;
|
|
40
|
+
height: 16px;
|
|
41
|
+
flex-shrink: 0;
|
|
42
|
+
background-color: currentColor;
|
|
43
|
+
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 16v-4'/%3E%3Cpath d='M12 8h.01'/%3E%3C/svg%3E") center / contain no-repeat;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* Reserve the icon column only when a title/description follows. */
|
|
47
|
+
& > * {
|
|
48
|
+
grid-column: 2;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
&[data-variant="destructive"] {
|
|
52
|
+
color: var(--sheerly-destructive);
|
|
53
|
+
|
|
54
|
+
&::before {
|
|
55
|
+
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 8v4'/%3E%3Cpath d='M12 16h.01'/%3E%3C/svg%3E");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.sheerly-alert-description {
|
|
59
|
+
color: oklch(from var(--sheerly-destructive) l c h / 90%);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
&[data-variant="success"] {
|
|
64
|
+
color: oklch(0.527 0.132 152.53);
|
|
65
|
+
|
|
66
|
+
&::before {
|
|
67
|
+
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21.801 10A10 10 0 1 1 17 3.335'/%3E%3Cpath d='m9 11 3 3L22 4'/%3E%3C/svg%3E");
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
&[data-variant="warning"] {
|
|
72
|
+
color: oklch(0.553 0.135 66.44);
|
|
73
|
+
|
|
74
|
+
&::before {
|
|
75
|
+
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3'/%3E%3Cpath d='M12 9v4'/%3E%3Cpath d='M12 17h.01'/%3E%3C/svg%3E");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
&[data-variant="info"] {
|
|
80
|
+
color: oklch(0.488 0.243 264.38);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.sheerly-alert-title {
|
|
85
|
+
color: inherit;
|
|
86
|
+
font-weight: 500;
|
|
87
|
+
line-height: 20px;
|
|
88
|
+
letter-spacing: -0.006em;
|
|
89
|
+
|
|
90
|
+
& a {
|
|
91
|
+
text-decoration: underline;
|
|
92
|
+
text-underline-offset: 3px;
|
|
93
|
+
|
|
94
|
+
&:hover {
|
|
95
|
+
color: var(--sheerly-foreground);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.sheerly-alert-description {
|
|
101
|
+
color: var(--sheerly-muted-foreground);
|
|
102
|
+
font-size: 14px;
|
|
103
|
+
line-height: 20px;
|
|
104
|
+
text-wrap: balance;
|
|
105
|
+
|
|
106
|
+
& a {
|
|
107
|
+
text-decoration: underline;
|
|
108
|
+
text-underline-offset: 3px;
|
|
109
|
+
|
|
110
|
+
&:hover {
|
|
111
|
+
color: var(--sheerly-foreground);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
& p:not(:last-child) {
|
|
116
|
+
margin-bottom: 16px;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/* Action pinned to the top-right corner. */
|
|
121
|
+
.sheerly-alert-action {
|
|
122
|
+
position: absolute;
|
|
123
|
+
top: 8px;
|
|
124
|
+
right: 8px;
|
|
125
|
+
grid-column: auto;
|
|
126
|
+
}
|
package/src/alert.tsx
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'react'
|
|
2
|
+
import { cn } from './cn'
|
|
3
|
+
|
|
4
|
+
export interface AlertProps extends HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
'data-variant'?: 'default' | 'destructive' | 'success' | 'info' | 'warning'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function Alert({ className, role = 'alert', ...props }: AlertProps) {
|
|
9
|
+
return <div role={role} className={cn('sheerly-alert', className)} {...props} />
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function AlertTitle({ className, ...props }: HTMLAttributes<HTMLDivElement>) {
|
|
13
|
+
return <div className={cn('sheerly-alert-title', className)} {...props} />
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function AlertDescription({
|
|
17
|
+
className,
|
|
18
|
+
...props
|
|
19
|
+
}: HTMLAttributes<HTMLDivElement>) {
|
|
20
|
+
return <div className={cn('sheerly-alert-description', className)} {...props} />
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function AlertAction({ className, ...props }: HTMLAttributes<HTMLDivElement>) {
|
|
24
|
+
return <div className={cn('sheerly-alert-action', className)} {...props} />
|
|
25
|
+
}
|