@lessly/ui 1.3.0 → 1.4.0
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 +40 -3
- package/dist/index.d.ts +5 -0
- package/dist/index.js +11 -10
- package/dist/styles.css +6 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -42,9 +42,46 @@ import { Button, useTheme } from '@lessly/ui';
|
|
|
42
42
|
import '@lessly/ui/styles.css';
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
Tailwind is what turns the kit's class names into CSS. The package ships **no
|
|
46
|
+
compiled utility CSS** — every consumer runs its own Tailwind over the token
|
|
47
|
+
preset (`tailwindcss >= 3.4`, an optional peer dependency, required only if you
|
|
48
|
+
consume the preset).
|
|
49
|
+
|
|
50
|
+
### Tailwind v4 (CSS-first)
|
|
51
|
+
|
|
52
|
+
Everything is declared in your CSS entry:
|
|
53
|
+
|
|
54
|
+
```css
|
|
55
|
+
@import 'tailwindcss';
|
|
56
|
+
/* The token preset. v4 has no `presets:` key of its own, so the preset is
|
|
57
|
+
loaded from a JS/TS config file — without this, `bg-bg-surface`,
|
|
58
|
+
`text-text-primary` and `gap-gutter` emit nothing at all. */
|
|
59
|
+
@config './tailwind.config.ts';
|
|
60
|
+
/* Token variables, `.light` overrides, fonts, base layer. */
|
|
61
|
+
@import '@lessly/ui/styles.css';
|
|
62
|
+
/* Scan the library. v4 does not scan `node_modules` on its own, and the kit's
|
|
63
|
+
components (Grid, Col, …) carry literal utilities (`md:col-span-5`,
|
|
64
|
+
`gap-gutter`) as strings inside `dist/index.js`. The glob matters: a bare
|
|
65
|
+
directory path is skipped, because Tailwind honours your `.gitignore` and
|
|
66
|
+
`node_modules/` is in it. */
|
|
67
|
+
@source './node_modules/@lessly/ui/dist/**/*.js';
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
with the config file next to it holding nothing but the preset:
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import type { Config } from 'tailwindcss';
|
|
74
|
+
import { lesslyPreset } from '@lessly/ui/tailwind-preset';
|
|
75
|
+
export default { presets: [lesslyPreset] } satisfies Config;
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Paths in `@source` and `@config` are relative to the CSS file. If your CSS entry
|
|
79
|
+
sits in `src/`, they read `'../tailwind.config.ts'` and
|
|
80
|
+
`'../node_modules/@lessly/ui/dist/**/*.js'`.
|
|
81
|
+
|
|
82
|
+
### Tailwind v3
|
|
83
|
+
|
|
84
|
+
The preset and the library scan both go in the JS config:
|
|
48
85
|
|
|
49
86
|
```ts
|
|
50
87
|
import { lesslyPreset } from '@lessly/ui/tailwind-preset';
|
package/dist/index.d.ts
CHANGED
|
@@ -128,6 +128,11 @@ interface CardProps extends Omit<React$1.HTMLAttributes<HTMLDivElement>, 'title'
|
|
|
128
128
|
* action no bar is drawn at all, so a list starts at the top of the card.
|
|
129
129
|
*/
|
|
130
130
|
title?: React$1.ReactNode;
|
|
131
|
+
/**
|
|
132
|
+
* The native HTML tooltip on the card's box, shown by the browser on hover. `title` is the
|
|
133
|
+
* visible heading here, so this is the only way to set the attribute.
|
|
134
|
+
*/
|
|
135
|
+
tooltip?: string;
|
|
131
136
|
action?: React$1.ReactNode;
|
|
132
137
|
/**
|
|
133
138
|
* `list` clips to the card's radius and hairlines between children.
|
package/dist/index.js
CHANGED
|
@@ -204,10 +204,11 @@ Button.displayName = "Button";
|
|
|
204
204
|
import * as React3 from "react";
|
|
205
205
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
206
206
|
var Card = React3.forwardRef(
|
|
207
|
-
({ className, title, action, variant = "default", children, ...props }, ref) => /* @__PURE__ */ jsxs2(
|
|
207
|
+
({ className, title, tooltip, action, variant = "default", children, ...props }, ref) => /* @__PURE__ */ jsxs2(
|
|
208
208
|
"div",
|
|
209
209
|
{
|
|
210
210
|
ref,
|
|
211
|
+
title: tooltip,
|
|
211
212
|
className: cn(
|
|
212
213
|
"rounded-xl border border-border-subtle bg-bg-surface text-text-primary shadow-sm",
|
|
213
214
|
variant === "list" && "overflow-hidden",
|
|
@@ -3886,21 +3887,21 @@ var ImageCropper = React57.forwardRef(
|
|
|
3886
3887
|
React57.useLayoutEffect(() => {
|
|
3887
3888
|
const el = stageRef.current;
|
|
3888
3889
|
if (!el) return void 0;
|
|
3889
|
-
const read = () => {
|
|
3890
|
-
const rect = el.getBoundingClientRect();
|
|
3890
|
+
const read = (entry) => {
|
|
3891
3891
|
const style = typeof getComputedStyle === "function" ? getComputedStyle(el) : null;
|
|
3892
3892
|
const edge = (value) => value ? parseFloat(value) || 0 : 0;
|
|
3893
3893
|
const bl = edge(style?.borderLeftWidth);
|
|
3894
3894
|
const bt = edge(style?.borderTopWidth);
|
|
3895
3895
|
inset.current = { left: bl, top: bt };
|
|
3896
|
-
const
|
|
3897
|
-
const
|
|
3896
|
+
const border = entry?.borderBoxSize?.[0];
|
|
3897
|
+
const w = border ? border.inlineSize - bl - edge(style?.borderRightWidth) : el.clientWidth;
|
|
3898
|
+
const h = border ? border.blockSize - bt - edge(style?.borderBottomWidth) : el.clientHeight;
|
|
3898
3899
|
if (w <= 0 || h <= 0) return;
|
|
3899
3900
|
setStage((prev) => prev.w === w && prev.h === h ? prev : { w, h });
|
|
3900
3901
|
};
|
|
3901
3902
|
read();
|
|
3902
3903
|
if (typeof ResizeObserver === "undefined") return void 0;
|
|
3903
|
-
const observer = new ResizeObserver(read);
|
|
3904
|
+
const observer = new ResizeObserver((entries) => read(entries[0]));
|
|
3904
3905
|
observer.observe(el);
|
|
3905
3906
|
return () => observer.disconnect();
|
|
3906
3907
|
}, []);
|
|
@@ -5107,13 +5108,13 @@ function ItemLabel({ item, kind }) {
|
|
|
5107
5108
|
const name = nameOf(item);
|
|
5108
5109
|
return /* @__PURE__ */ jsx85("span", { className: cn("min-w-0 flex-1 truncate", !name && "text-text-tertiary"), children: name ?? UNNAMED[kind] });
|
|
5109
5110
|
}
|
|
5110
|
-
function Mark2({ item, size }) {
|
|
5111
|
+
function Mark2({ item, size, reserve }) {
|
|
5111
5112
|
const box = size === "md" ? "size-7" : "size-5";
|
|
5112
5113
|
if (item.icon) {
|
|
5113
5114
|
return /* @__PURE__ */ jsx85("span", { className: cn("flex shrink-0 items-center justify-center overflow-hidden rounded-md", box), "aria-hidden": "true", children: item.icon });
|
|
5114
5115
|
}
|
|
5115
5116
|
const initial = nameOf(item)?.trim().charAt(0).toUpperCase();
|
|
5116
|
-
if (!initial) return null;
|
|
5117
|
+
if (!initial) return reserve ? /* @__PURE__ */ jsx85("span", { "aria-hidden": "true", className: cn("shrink-0", box) }) : null;
|
|
5117
5118
|
return /* @__PURE__ */ jsx85(
|
|
5118
5119
|
"span",
|
|
5119
5120
|
{
|
|
@@ -5172,7 +5173,7 @@ function OrgProductSwitcher({
|
|
|
5172
5173
|
children: [
|
|
5173
5174
|
/* @__PURE__ */ jsx85(DropdownMenuLabel, { className: sectionLabel, children: "Organizations" }),
|
|
5174
5175
|
organizations.map((o) => /* @__PURE__ */ jsxs56(DropdownMenuItem, { className: menuItem, onSelect: () => onOrgSelect(o.id), children: [
|
|
5175
|
-
/* @__PURE__ */ jsx85(Mark2, { item: o, size: "sm" }),
|
|
5176
|
+
/* @__PURE__ */ jsx85(Mark2, { item: o, size: "sm", reserve: true }),
|
|
5176
5177
|
/* @__PURE__ */ jsx85(ItemLabel, { item: o, kind: "organization" }),
|
|
5177
5178
|
o.id === activeOrgId && /* @__PURE__ */ jsx85(Check9, { className: "size-4 shrink-0 text-text-secondary", "aria-hidden": "true" })
|
|
5178
5179
|
] }, o.id)),
|
|
@@ -5180,7 +5181,7 @@ function OrgProductSwitcher({
|
|
|
5180
5181
|
/* @__PURE__ */ jsx85(DropdownMenuSeparator, { className: "mx-0 shrink-0 bg-border-subtle" }),
|
|
5181
5182
|
/* @__PURE__ */ jsx85(DropdownMenuLabel, { className: sectionLabel, children: orgName ? `${orgName} \xB7 Products` : "Products" }),
|
|
5182
5183
|
products.map((p) => /* @__PURE__ */ jsxs56(DropdownMenuItem, { className: menuItem, onSelect: () => onProductSelect?.(p.id), children: [
|
|
5183
|
-
/* @__PURE__ */ jsx85(Mark2, { item: p, size: "sm" }),
|
|
5184
|
+
/* @__PURE__ */ jsx85(Mark2, { item: p, size: "sm", reserve: true }),
|
|
5184
5185
|
/* @__PURE__ */ jsx85(ItemLabel, { item: p, kind: "product" }),
|
|
5185
5186
|
p.id === activeProductId && /* @__PURE__ */ jsx85(Check9, { className: "size-4 shrink-0 text-text-secondary", "aria-hidden": "true" })
|
|
5186
5187
|
] }, p.id))
|
package/dist/styles.css
CHANGED
|
@@ -643,6 +643,12 @@
|
|
|
643
643
|
/* === Animation layer (tw-animate-css, compiled) — see scripts/build-styles.mjs === */
|
|
644
644
|
/*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */
|
|
645
645
|
@layer properties;
|
|
646
|
+
.slide-in-from-left-2 {
|
|
647
|
+
--tw-enter-translate-x: calc(2*var(--spacing)*-1);
|
|
648
|
+
}
|
|
649
|
+
.slide-in-from-top-2 {
|
|
650
|
+
--tw-enter-translate-y: calc(2*var(--spacing)*-1);
|
|
651
|
+
}
|
|
646
652
|
.data-\[motion\=from-end\]\:slide-in-from-right-52 {
|
|
647
653
|
&[data-motion="from-end"] {
|
|
648
654
|
--tw-enter-translate-x: calc(52*var(--spacing));
|