@maple-kit/ui 0.1.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/LICENSE +202 -0
- package/NOTICE +9 -0
- package/README.md +39 -0
- package/dist/composer/actions.d.ts +15 -0
- package/dist/composer/actions.js +59 -0
- package/dist/composer/attachments.d.ts +33 -0
- package/dist/composer/attachments.js +166 -0
- package/dist/composer/badge.d.ts +13 -0
- package/dist/composer/badge.js +25 -0
- package/dist/composer/body.d.ts +13 -0
- package/dist/composer/body.js +119 -0
- package/dist/composer/composer.d.ts +23 -0
- package/dist/composer/composer.js +122 -0
- package/dist/composer/css.js +559 -0
- package/dist/composer/detail.d.ts +32 -0
- package/dist/composer/detail.js +102 -0
- package/dist/composer/emoji.d.ts +54 -0
- package/dist/composer/emoji.js +131 -0
- package/dist/composer/index.d.ts +15 -0
- package/dist/composer/index.js +15 -0
- package/dist/composer/inset.js +20 -0
- package/dist/composer/leave.d.ts +19 -0
- package/dist/composer/leave.js +34 -0
- package/dist/composer/peek.d.ts +21 -0
- package/dist/composer/peek.js +29 -0
- package/dist/composer/phrase.d.ts +27 -0
- package/dist/composer/phrase.js +30 -0
- package/dist/composer/picker-emoji.d.ts +34 -0
- package/dist/composer/picker-emoji.js +48 -0
- package/dist/composer/prompt.js +31 -0
- package/dist/composer/scope.d.ts +11 -0
- package/dist/composer/scope.js +16 -0
- package/dist/composer/target.d.ts +13 -0
- package/dist/composer/target.js +45 -0
- package/dist/context.d.ts +21 -0
- package/dist/context.js +16 -0
- package/dist/data.d.ts +52 -0
- package/dist/data.js +30 -0
- package/dist/icons/branch.d.ts +4 -0
- package/dist/icons/branch.js +8 -0
- package/dist/icons/cog.d.ts +4 -0
- package/dist/icons/cog.js +8 -0
- package/dist/icons/commit.d.ts +4 -0
- package/dist/icons/commit.js +5 -0
- package/dist/icons/crossfade.d.ts +15 -0
- package/dist/icons/crossfade.js +27 -0
- package/dist/icons/element.d.ts +4 -0
- package/dist/icons/element.js +5 -0
- package/dist/icons/icon.d.ts +24 -0
- package/dist/icons/icon.js +27 -0
- package/dist/icons/index.d.ts +13 -0
- package/dist/icons/index.js +13 -0
- package/dist/icons/noplace.d.ts +4 -0
- package/dist/icons/noplace.js +5 -0
- package/dist/icons/region.d.ts +4 -0
- package/dist/icons/region.js +8 -0
- package/dist/icons/smiley.d.ts +4 -0
- package/dist/icons/smiley.js +8 -0
- package/dist/icons/sparkle.d.ts +4 -0
- package/dist/icons/sparkle.js +8 -0
- package/dist/icons/target.d.ts +4 -0
- package/dist/icons/target.js +5 -0
- package/dist/icons/text.d.ts +4 -0
- package/dist/icons/text.js +5 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +11 -0
- package/dist/island/account.d.ts +10 -0
- package/dist/island/account.js +52 -0
- package/dist/island/comments.d.ts +24 -0
- package/dist/island/comments.js +40 -0
- package/dist/island/content.d.ts +10 -0
- package/dist/island/content.js +26 -0
- package/dist/island/context.d.ts +58 -0
- package/dist/island/context.js +23 -0
- package/dist/island/css.d.ts +13 -0
- package/dist/island/css.js +1020 -0
- package/dist/island/drag.d.ts +10 -0
- package/dist/island/drag.js +77 -0
- package/dist/island/filters.d.ts +10 -0
- package/dist/island/filters.js +63 -0
- package/dist/island/header.d.ts +32 -0
- package/dist/island/header.js +47 -0
- package/dist/island/index.d.ts +18 -0
- package/dist/island/index.js +18 -0
- package/dist/island/island.d.ts +12 -0
- package/dist/island/island.js +111 -0
- package/dist/island/item.d.ts +12 -0
- package/dist/island/item.js +158 -0
- package/dist/island/language.d.ts +55 -0
- package/dist/island/language.js +125 -0
- package/dist/island/leaf.js +17 -0
- package/dist/island/list.d.ts +12 -0
- package/dist/island/list.js +31 -0
- package/dist/island/new-comment.d.ts +18 -0
- package/dist/island/new-comment.js +56 -0
- package/dist/island/settings.d.ts +10 -0
- package/dist/island/settings.js +134 -0
- package/dist/island/stagger.d.ts +12 -0
- package/dist/island/stagger.js +4 -0
- package/dist/island/time.d.ts +17 -0
- package/dist/island/time.js +29 -0
- package/dist/island/trigger.d.ts +10 -0
- package/dist/island/trigger.js +39 -0
- package/dist/language.d.ts +45 -0
- package/dist/language.js +66 -0
- package/dist/maple.d.ts +25 -0
- package/dist/maple.js +65 -0
- package/dist/marks/avatar.d.ts +16 -0
- package/dist/marks/avatar.js +36 -0
- package/dist/marks/css.d.ts +12 -0
- package/dist/marks/css.js +371 -0
- package/dist/marks/frame.d.ts +25 -0
- package/dist/marks/frame.js +53 -0
- package/dist/marks/geometry.d.ts +55 -0
- package/dist/marks/geometry.js +61 -0
- package/dist/marks/index.d.ts +14 -0
- package/dist/marks/index.js +14 -0
- package/dist/marks/label.d.ts +23 -0
- package/dist/marks/label.js +31 -0
- package/dist/marks/layer.d.ts +16 -0
- package/dist/marks/layer.js +194 -0
- package/dist/marks/leaf.d.ts +18 -0
- package/dist/marks/leaf.js +7 -0
- package/dist/marks/mark.d.ts +28 -0
- package/dist/marks/mark.js +43 -0
- package/dist/marks/nudge.d.ts +50 -0
- package/dist/marks/nudge.js +76 -0
- package/dist/marks/paint.d.ts +11 -0
- package/dist/marks/paint.js +19 -0
- package/dist/marks/placement.d.ts +24 -0
- package/dist/marks/placement.js +28 -0
- package/dist/marks/ring.d.ts +28 -0
- package/dist/marks/ring.js +85 -0
- package/dist/marks/shape.d.ts +21 -0
- package/dist/marks/shape.js +51 -0
- package/dist/notice/css.d.ts +11 -0
- package/dist/notice/css.js +74 -0
- package/dist/notice/index.d.ts +4 -0
- package/dist/notice/index.js +4 -0
- package/dist/notice/language.d.ts +15 -0
- package/dist/notice/language.js +14 -0
- package/dist/notice/notice.d.ts +14 -0
- package/dist/notice/notice.js +49 -0
- package/dist/part.d.ts +9 -0
- package/dist/part.js +11 -0
- package/dist/picker/css.d.ts +13 -0
- package/dist/picker/css.js +141 -0
- package/dist/picker/index.d.ts +6 -0
- package/dist/picker/index.js +6 -0
- package/dist/picker/language.d.ts +14 -0
- package/dist/picker/language.js +17 -0
- package/dist/picker/picker.d.ts +18 -0
- package/dist/picker/picker.js +164 -0
- package/dist/picker/session.d.ts +16 -0
- package/dist/picker/session.js +35 -0
- package/dist/picker/target.d.ts +23 -0
- package/dist/picker/target.js +37 -0
- package/dist/root.d.ts +42 -0
- package/dist/root.js +75 -0
- package/dist/shots.js +32 -0
- package/dist/slot.d.ts +28 -0
- package/dist/slot.js +52 -0
- package/dist/slots.d.ts +24 -0
- package/dist/slots.js +75 -0
- package/dist/stylesheet.d.ts +15 -0
- package/dist/stylesheet.js +188 -0
- package/dist/theme.d.ts +20 -0
- package/dist/theme.js +13 -0
- package/dist/tip.d.ts +40 -0
- package/dist/tip.js +82 -0
- package/dist/tokens.d.ts +28 -0
- package/dist/tokens.js +180 -0
- package/package.json +56 -0
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { COLOR_TOKENS, MOTION_TOKENS, RADIUS_TOKENS, REDUCED_MOTION_TOKENS, SHADOW_TOKENS, SIZE_TOKENS, TYPE_TOKENS } from "./tokens.js";
|
|
2
|
+
import { composerCss } from "./composer/css.js";
|
|
3
|
+
import { islandCss } from "./island/css.js";
|
|
4
|
+
import { marksCss } from "./marks/css.js";
|
|
5
|
+
import { noticeCss } from "./notice/css.js";
|
|
6
|
+
import { pickerCss } from "./picker/css.js";
|
|
7
|
+
//#region src/stylesheet.ts
|
|
8
|
+
const SCHEME_ATTRIBUTE = "data-mk-scheme";
|
|
9
|
+
const DARK_HOST = `:host([${SCHEME_ATTRIBUTE}="dark"])`;
|
|
10
|
+
function declare(tokens) {
|
|
11
|
+
return Object.entries(tokens).map(([name, value]) => ` ${name}: ${value};`).join("\n");
|
|
12
|
+
}
|
|
13
|
+
function declareThemed(tokens, scheme) {
|
|
14
|
+
return Object.entries(tokens).map(([name, value]) => ` ${name}: ${value[scheme]};`).join("\n");
|
|
15
|
+
}
|
|
16
|
+
function tokenCss() {
|
|
17
|
+
return [
|
|
18
|
+
`:host {`,
|
|
19
|
+
declareThemed(COLOR_TOKENS, "light"),
|
|
20
|
+
declareThemed(SHADOW_TOKENS, "light"),
|
|
21
|
+
declare(RADIUS_TOKENS),
|
|
22
|
+
declare(TYPE_TOKENS),
|
|
23
|
+
declare(SIZE_TOKENS),
|
|
24
|
+
declare(MOTION_TOKENS),
|
|
25
|
+
` color-scheme: light;`,
|
|
26
|
+
`}`,
|
|
27
|
+
``,
|
|
28
|
+
`${DARK_HOST} {`,
|
|
29
|
+
declareThemed(COLOR_TOKENS, "dark"),
|
|
30
|
+
declareThemed(SHADOW_TOKENS, "dark"),
|
|
31
|
+
` color-scheme: dark;`,
|
|
32
|
+
`}`,
|
|
33
|
+
``,
|
|
34
|
+
`@media (prefers-reduced-motion: reduce) {`,
|
|
35
|
+
` :host {`,
|
|
36
|
+
declare(REDUCED_MOTION_TOKENS).split("\n").map((line) => ` ${line}`).join("\n"),
|
|
37
|
+
` }`,
|
|
38
|
+
`}`
|
|
39
|
+
].join("\n");
|
|
40
|
+
}
|
|
41
|
+
function ruleCss() {
|
|
42
|
+
return `
|
|
43
|
+
:host {
|
|
44
|
+
display: block;
|
|
45
|
+
font-family: var(--mk-font);
|
|
46
|
+
font-size: 13px;
|
|
47
|
+
font-weight: 400;
|
|
48
|
+
font-style: normal;
|
|
49
|
+
font-variant: normal;
|
|
50
|
+
letter-spacing: normal;
|
|
51
|
+
line-height: 1.45;
|
|
52
|
+
text-align: left;
|
|
53
|
+
color: var(--mk-fg);
|
|
54
|
+
-webkit-font-smoothing: antialiased;
|
|
55
|
+
-moz-osx-font-smoothing: grayscale;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
*,
|
|
59
|
+
*::before,
|
|
60
|
+
*::after {
|
|
61
|
+
box-sizing: border-box;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.mk-layer {
|
|
65
|
+
position: absolute;
|
|
66
|
+
inset: 0;
|
|
67
|
+
pointer-events: none;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.mk-live {
|
|
71
|
+
pointer-events: auto;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.mk-surface {
|
|
75
|
+
background: var(--mk-bg);
|
|
76
|
+
border: 1px solid var(--mk-line-firm);
|
|
77
|
+
border-radius: var(--mk-r);
|
|
78
|
+
box-shadow: var(--mk-sh2);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
${DARK_HOST} .mk-surface {
|
|
82
|
+
box-shadow: var(--mk-sh2), inset 0 1px 0 oklch(1 0 0 / 0.045);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.mk-num {
|
|
86
|
+
font-variant-numeric: tabular-nums;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.mk-mono {
|
|
90
|
+
font-family: var(--mk-mono);
|
|
91
|
+
font-variant-numeric: tabular-nums;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.mk-body {
|
|
95
|
+
text-wrap: pretty;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.mk-title,
|
|
99
|
+
h1,
|
|
100
|
+
h2,
|
|
101
|
+
h3 {
|
|
102
|
+
text-wrap: balance;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.mk-shot {
|
|
106
|
+
outline: 1px solid var(--mk-shot-edge);
|
|
107
|
+
outline-offset: -1px;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* No radius here: an outline already follows the control's own corners, and
|
|
111
|
+
forcing one squared off every pill in the overlay the moment it took focus.
|
|
112
|
+
The two controls that carry no radius of their own are given one below. */
|
|
113
|
+
:where(a, button, input, textarea, [role="button"], [tabindex]):focus-visible {
|
|
114
|
+
outline: 2px solid var(--mk-accent);
|
|
115
|
+
outline-offset: 2px;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.mk-press {
|
|
119
|
+
transition: transform var(--mk-dur-fade) var(--mk-ease-surface);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.mk-press:active {
|
|
123
|
+
transform: scale(var(--mk-press));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.mk-hit {
|
|
127
|
+
position: relative;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.mk-hit::after {
|
|
131
|
+
content: "";
|
|
132
|
+
position: absolute;
|
|
133
|
+
top: 50%;
|
|
134
|
+
left: 50%;
|
|
135
|
+
width: max(100%, var(--mk-hit));
|
|
136
|
+
height: max(100%, var(--mk-hit));
|
|
137
|
+
transform: translate(-50%, -50%);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.mk-track {
|
|
141
|
+
transition: opacity var(--mk-dur-fade) var(--mk-ease-surface);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.mk-icon-swap {
|
|
145
|
+
display: inline-grid;
|
|
146
|
+
place-items: center;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.mk-icon-swap > * {
|
|
150
|
+
grid-area: 1 / 1;
|
|
151
|
+
transition:
|
|
152
|
+
opacity var(--mk-dur-swap) var(--mk-ease-swap),
|
|
153
|
+
transform var(--mk-dur-swap) var(--mk-ease-swap),
|
|
154
|
+
filter var(--mk-dur-swap) var(--mk-ease-swap);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.mk-icon-swap > [data-mk-icon="out"] {
|
|
158
|
+
opacity: 0;
|
|
159
|
+
transform: scale(var(--mk-icon-scale));
|
|
160
|
+
filter: blur(var(--mk-icon-blur));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.mk-icon-swap > [data-mk-icon="in"] {
|
|
164
|
+
opacity: 1;
|
|
165
|
+
transform: scale(1);
|
|
166
|
+
filter: blur(0);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
@media (max-width: 639px) {
|
|
170
|
+
:host {
|
|
171
|
+
--mk-composer-w: 100%;
|
|
172
|
+
--mk-composer-r: var(--mk-r) var(--mk-r) 0 0;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
${islandCss()}
|
|
177
|
+
${composerCss()}
|
|
178
|
+
${marksCss()}
|
|
179
|
+
${noticeCss()}
|
|
180
|
+
${pickerCss()}
|
|
181
|
+
`.trim();
|
|
182
|
+
}
|
|
183
|
+
function buildOverlayCss() {
|
|
184
|
+
return `${tokenCss()}\n\n${ruleCss()}\n`;
|
|
185
|
+
}
|
|
186
|
+
const OVERLAY_CSS = buildOverlayCss();
|
|
187
|
+
//#endregion
|
|
188
|
+
export { OVERLAY_CSS, SCHEME_ATTRIBUTE, ruleCss, tokenCss };
|
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Scheme } from "@maple-kit/core/client";
|
|
2
|
+
//#region src/theme.d.ts
|
|
3
|
+
/** The overlay's scheme and the host's, which are not the same scheme. */
|
|
4
|
+
export interface OverlayTheme {
|
|
5
|
+
/** What the overlay is drawn in. */
|
|
6
|
+
readonly scheme: Scheme;
|
|
7
|
+
/** What the host page is in, which is what a comment records. */
|
|
8
|
+
readonly hostScheme: Scheme;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The overlay's scheme, as the viewer last asked for it.
|
|
12
|
+
*
|
|
13
|
+
* The preference is the controller's, not this component's: it is remembered
|
|
14
|
+
* per origin and settable from the island, so a prop here would be a second
|
|
15
|
+
* source for the same fact and would win on every remount. An application
|
|
16
|
+
* still chooses the default by passing `theme` to `Maple.Root`, which is read
|
|
17
|
+
* once into the config the controller starts from.
|
|
18
|
+
*/
|
|
19
|
+
export declare function useOverlayScheme(): OverlayTheme;
|
|
20
|
+
//#endregion
|
package/dist/theme.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { overlaySchemeFor } from "@maple-kit/core/client";
|
|
3
|
+
import { useMaple } from "@maple-kit/react";
|
|
4
|
+
//#region src/theme.ts
|
|
5
|
+
function useOverlayScheme() {
|
|
6
|
+
const { theme, themePreference } = useMaple();
|
|
7
|
+
return useMemo(() => ({
|
|
8
|
+
scheme: overlaySchemeFor(themePreference, theme),
|
|
9
|
+
hostScheme: theme.host
|
|
10
|
+
}), [themePreference, theme]);
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
13
|
+
export { useOverlayScheme };
|
package/dist/tip.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ElementType, ReactNode } from "react";
|
|
2
|
+
//#region src/tip.d.ts
|
|
3
|
+
/** A chip, its sentence, and whatever the chip is drawn as. */
|
|
4
|
+
export interface TipProps {
|
|
5
|
+
/** The sentence. Never rendered in the row itself. */
|
|
6
|
+
readonly sentence: string;
|
|
7
|
+
/** What the chip shows: a number, a percentage, a path. */
|
|
8
|
+
readonly children?: ReactNode;
|
|
9
|
+
readonly className?: string;
|
|
10
|
+
/** The element the chip is drawn as. A `button` when it also does something. */
|
|
11
|
+
readonly as?: ElementType;
|
|
12
|
+
/**
|
|
13
|
+
* How long the pointer has to rest before it opens. The default is the
|
|
14
|
+
* stylesheet's intent delay; a fact nobody came looking for takes longer.
|
|
15
|
+
*/
|
|
16
|
+
readonly delayMs?: number;
|
|
17
|
+
/** Spread onto the trigger, for a chip that is also a control. */
|
|
18
|
+
readonly triggerProps?: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Reachable by keyboard as well as by pointer, because a fact only a mouse
|
|
22
|
+
* can read is a fact half the reviewers do not have.
|
|
23
|
+
*/
|
|
24
|
+
export declare const Tip: import("react").ForwardRefExoticComponent<TipProps & import("react").RefAttributes<HTMLElement>>;
|
|
25
|
+
/**
|
|
26
|
+
* Below the chip, or above it when there is no room — measured against the
|
|
27
|
+
* viewport, because the top layer is positioned against the viewport and not
|
|
28
|
+
* against whatever the chip happened to be inside.
|
|
29
|
+
*/
|
|
30
|
+
export declare function tipSpot(anchor: DOMRect, tip: {
|
|
31
|
+
readonly width: number;
|
|
32
|
+
readonly height: number;
|
|
33
|
+
}, view: {
|
|
34
|
+
readonly width: number;
|
|
35
|
+
readonly height: number;
|
|
36
|
+
}): {
|
|
37
|
+
readonly x: number;
|
|
38
|
+
readonly y: number;
|
|
39
|
+
};
|
|
40
|
+
//#endregion
|
package/dist/tip.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { cx } from "./part.js";
|
|
2
|
+
import { createElement, forwardRef, useCallback, useId, useRef } from "react";
|
|
3
|
+
//#region src/tip.ts
|
|
4
|
+
const GAP_PX = 6;
|
|
5
|
+
const EDGE_PX = 8;
|
|
6
|
+
const BELOW = "data-mk-below";
|
|
7
|
+
const Tip = forwardRef(function Tip(props, ref) {
|
|
8
|
+
const id = useId();
|
|
9
|
+
const trigger = useRef(null);
|
|
10
|
+
const tip = useRef(null);
|
|
11
|
+
const waiting = useRef(void 0);
|
|
12
|
+
const { delayMs = 0 } = props;
|
|
13
|
+
const reveal = useCallback(() => {
|
|
14
|
+
const node = tip.current;
|
|
15
|
+
const from = trigger.current;
|
|
16
|
+
if (!node || !from) return;
|
|
17
|
+
open(node);
|
|
18
|
+
place(node, from.getBoundingClientRect());
|
|
19
|
+
}, []);
|
|
20
|
+
const show = useCallback(() => {
|
|
21
|
+
if (delayMs <= 0) return reveal();
|
|
22
|
+
waiting.current = window.setTimeout(reveal, delayMs);
|
|
23
|
+
}, [delayMs, reveal]);
|
|
24
|
+
const hide = useCallback(() => {
|
|
25
|
+
if (waiting.current !== void 0) window.clearTimeout(waiting.current);
|
|
26
|
+
waiting.current = void 0;
|
|
27
|
+
close(tip.current);
|
|
28
|
+
}, []);
|
|
29
|
+
const Element = props.as ?? "span";
|
|
30
|
+
return createElement(Element, {
|
|
31
|
+
...props.triggerProps,
|
|
32
|
+
className: cx("mk-tipped", props.className),
|
|
33
|
+
tabIndex: 0,
|
|
34
|
+
"aria-describedby": id,
|
|
35
|
+
ref: keep(ref, trigger),
|
|
36
|
+
onPointerEnter: show,
|
|
37
|
+
onPointerLeave: hide,
|
|
38
|
+
onFocus: show,
|
|
39
|
+
onBlur: hide
|
|
40
|
+
}, props.children, createElement("span", {
|
|
41
|
+
id,
|
|
42
|
+
popover: "manual",
|
|
43
|
+
role: "tooltip",
|
|
44
|
+
className: "mk-tip",
|
|
45
|
+
ref: tip,
|
|
46
|
+
children: props.sentence
|
|
47
|
+
}));
|
|
48
|
+
});
|
|
49
|
+
function open(node) {
|
|
50
|
+
if (!node.matches(":popover-open")) node.showPopover();
|
|
51
|
+
}
|
|
52
|
+
function close(node) {
|
|
53
|
+
if (node?.matches(":popover-open") === true) node.hidePopover();
|
|
54
|
+
}
|
|
55
|
+
function tipSpot(anchor, tip, view) {
|
|
56
|
+
const below = anchor.bottom + GAP_PX;
|
|
57
|
+
const y = below + tip.height <= view.height - EDGE_PX ? below : Math.max(EDGE_PX, anchor.top - GAP_PX - tip.height);
|
|
58
|
+
const wanted = anchor.left + anchor.width / 2 - tip.width / 2;
|
|
59
|
+
const last = view.width - EDGE_PX - tip.width;
|
|
60
|
+
return {
|
|
61
|
+
x: Math.min(Math.max(EDGE_PX, wanted), Math.max(EDGE_PX, last)),
|
|
62
|
+
y
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
function place(node, anchor) {
|
|
66
|
+
const spot = tipSpot(anchor, node.getBoundingClientRect(), {
|
|
67
|
+
width: window.innerWidth,
|
|
68
|
+
height: window.innerHeight
|
|
69
|
+
});
|
|
70
|
+
node.toggleAttribute(BELOW, spot.y >= anchor.bottom);
|
|
71
|
+
node.style.setProperty("--mk-x", `${String(Math.round(spot.x))}px`);
|
|
72
|
+
node.style.setProperty("--mk-y", `${String(Math.round(spot.y))}px`);
|
|
73
|
+
}
|
|
74
|
+
function keep(ref, own) {
|
|
75
|
+
return (node) => {
|
|
76
|
+
own.current = node;
|
|
77
|
+
if (typeof ref === "function") ref(node);
|
|
78
|
+
else if (ref) ref.current = node;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//#endregion
|
|
82
|
+
export { Tip, tipSpot };
|
package/dist/tokens.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
//#region src/tokens.d.ts
|
|
2
|
+
/** Concentric: outer = inner + padding. 5 + 2 = 7, 7 + 3 = 10. */
|
|
3
|
+
export declare const RADIUS_TOKENS: Readonly<Record<string, string>>;
|
|
4
|
+
/**
|
|
5
|
+
* The directive's motion table, and the only durations and easings in the
|
|
6
|
+
* package. Overshoot appears on entrance easing alone; every surface — open,
|
|
7
|
+
* close, slide, resize, reposition — uses `--mk-ease-surface`. There is no
|
|
8
|
+
* close duration longer than its open and no delay token for a close.
|
|
9
|
+
*/
|
|
10
|
+
export declare const MOTION_TOKENS: Readonly<Record<string, string>>;
|
|
11
|
+
/**
|
|
12
|
+
* Reduced motion reduces the motion; it never removes the feedback. Distance,
|
|
13
|
+
* pre-scale and stagger collapse to nothing and every duration lands at or
|
|
14
|
+
* under 100ms, so what is left of a transition is its opacity. Every entrance
|
|
15
|
+
* distance is a token for that reason: a keyframe spelling `12px` keeps moving.
|
|
16
|
+
*/
|
|
17
|
+
export declare const REDUCED_MOTION_TOKENS: Readonly<Record<string, string>>;
|
|
18
|
+
/**
|
|
19
|
+
* Set with `setProperty` on one element, never declared and never written as a
|
|
20
|
+
* generated rule: a rule per reviewer is a stylesheet that grows with the team.
|
|
21
|
+
*/
|
|
22
|
+
export declare const RUNTIME_TOKENS: readonly string[];
|
|
23
|
+
/**
|
|
24
|
+
* The composer is a panel above this and a sheet below it. It is a width, not a
|
|
25
|
+
* variant prop, so it lives here rather than in a `variant="sheet"`.
|
|
26
|
+
*/
|
|
27
|
+
export declare const SHEET_BREAKPOINT_PX = 640;
|
|
28
|
+
//#endregion
|
package/dist/tokens.js
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
//#region src/tokens.ts
|
|
2
|
+
const COLOR_TOKENS = {
|
|
3
|
+
"--mk-bg": {
|
|
4
|
+
light: "oklch(1 0 0)",
|
|
5
|
+
dark: "oklch(0.238 0.011 265)"
|
|
6
|
+
},
|
|
7
|
+
"--mk-sunk": {
|
|
8
|
+
light: "oklch(0.968 0.003 265)",
|
|
9
|
+
dark: "oklch(0.193 0.010 265)"
|
|
10
|
+
},
|
|
11
|
+
"--mk-fg": {
|
|
12
|
+
light: "oklch(0.23 0.012 265)",
|
|
13
|
+
dark: "oklch(0.975 0.003 265)"
|
|
14
|
+
},
|
|
15
|
+
"--mk-muted": {
|
|
16
|
+
light: "oklch(0.53 0.014 265)",
|
|
17
|
+
dark: "oklch(0.79 0.011 265)"
|
|
18
|
+
},
|
|
19
|
+
"--mk-faint": {
|
|
20
|
+
light: "oklch(0.66 0.012 265)",
|
|
21
|
+
dark: "oklch(0.665 0.012 265)"
|
|
22
|
+
},
|
|
23
|
+
"--mk-line": {
|
|
24
|
+
light: "oklch(0.915 0.005 265)",
|
|
25
|
+
dark: "oklch(0.365 0.012 265)"
|
|
26
|
+
},
|
|
27
|
+
"--mk-line-firm": {
|
|
28
|
+
light: "oklch(0.86 0.007 265)",
|
|
29
|
+
dark: "oklch(0.47 0.015 265)"
|
|
30
|
+
},
|
|
31
|
+
"--mk-accent": {
|
|
32
|
+
light: "oklch(0.44 0.075 128)",
|
|
33
|
+
dark: "oklch(0.76 0.1 122)"
|
|
34
|
+
},
|
|
35
|
+
"--mk-accent-ink": {
|
|
36
|
+
light: "oklch(0.981 0.034 100)",
|
|
37
|
+
dark: "oklch(0.22 0.040 128)"
|
|
38
|
+
},
|
|
39
|
+
"--mk-accent-sub": {
|
|
40
|
+
light: "oklch(0.958 0.028 122)",
|
|
41
|
+
dark: "oklch(0.30 0.040 124)"
|
|
42
|
+
},
|
|
43
|
+
"--mk-ok": {
|
|
44
|
+
light: "oklch(0.52 0.11 155)",
|
|
45
|
+
dark: "oklch(0.74 0.12 155)"
|
|
46
|
+
},
|
|
47
|
+
"--mk-ok-sub": {
|
|
48
|
+
light: "oklch(0.955 0.03 155)",
|
|
49
|
+
dark: "oklch(0.29 0.05 155)"
|
|
50
|
+
},
|
|
51
|
+
"--mk-warn": {
|
|
52
|
+
light: "oklch(0.60 0.13 82)",
|
|
53
|
+
dark: "oklch(0.82 0.13 82)"
|
|
54
|
+
},
|
|
55
|
+
"--mk-warn-sub": {
|
|
56
|
+
light: "oklch(0.962 0.05 82)",
|
|
57
|
+
dark: "oklch(0.31 0.06 82)"
|
|
58
|
+
},
|
|
59
|
+
"--mk-lost": {
|
|
60
|
+
light: "oklch(0.52 0.11 305)",
|
|
61
|
+
dark: "oklch(0.76 0.11 305)"
|
|
62
|
+
},
|
|
63
|
+
"--mk-lost-sub": {
|
|
64
|
+
light: "oklch(0.958 0.028 305)",
|
|
65
|
+
dark: "oklch(0.29 0.05 305)"
|
|
66
|
+
},
|
|
67
|
+
"--mk-info": {
|
|
68
|
+
light: "oklch(0.53 0.12 248)",
|
|
69
|
+
dark: "oklch(0.74 0.12 248)"
|
|
70
|
+
},
|
|
71
|
+
"--mk-info-sub": {
|
|
72
|
+
light: "oklch(0.958 0.032 248)",
|
|
73
|
+
dark: "oklch(0.28 0.05 248)"
|
|
74
|
+
},
|
|
75
|
+
"--mk-maple": {
|
|
76
|
+
light: "oklch(0.56 0.12 60)",
|
|
77
|
+
dark: "oklch(0.72 0.125 62)"
|
|
78
|
+
},
|
|
79
|
+
"--mk-maple-sub": {
|
|
80
|
+
light: "oklch(0.965 0.030 62)",
|
|
81
|
+
dark: "oklch(0.30 0.050 58)"
|
|
82
|
+
},
|
|
83
|
+
"--mk-shot-edge": {
|
|
84
|
+
light: "oklch(0 0 0 / 0.1)",
|
|
85
|
+
dark: "oklch(1 0 0 / 0.1)"
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const SHADOW_TOKENS = {
|
|
89
|
+
"--mk-sh1": {
|
|
90
|
+
light: "0 1px 2px oklch(0.2 0.02 265 / 0.08)",
|
|
91
|
+
dark: "0 1px 2px oklch(0 0 0 / 0.45)"
|
|
92
|
+
},
|
|
93
|
+
"--mk-sh2": {
|
|
94
|
+
light: "0 6px 18px oklch(0.2 0.02 265 / 0.12), 0 1px 3px oklch(0.2 0.02 265 / 0.08)",
|
|
95
|
+
dark: "0 6px 18px oklch(0 0 0 / 0.5), 0 1px 3px oklch(0 0 0 / 0.35)"
|
|
96
|
+
},
|
|
97
|
+
"--mk-sh3": {
|
|
98
|
+
light: "0 20px 48px oklch(0.2 0.02 265 / 0.20), 0 2px 8px oklch(0.2 0.02 265 / 0.10)",
|
|
99
|
+
dark: "0 20px 48px oklch(0 0 0 / 0.6), 0 2px 8px oklch(0 0 0 / 0.4)"
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
const RADIUS_TOKENS = {
|
|
103
|
+
"--mk-r": "10px",
|
|
104
|
+
"--mk-r-sm": "7px",
|
|
105
|
+
"--mk-r-xs": "5px"
|
|
106
|
+
};
|
|
107
|
+
const TYPE_TOKENS = {
|
|
108
|
+
"--mk-font": "ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif",
|
|
109
|
+
"--mk-mono": "ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace"
|
|
110
|
+
};
|
|
111
|
+
const SIZE_TOKENS = {
|
|
112
|
+
"--mk-hit": "40px",
|
|
113
|
+
"--mk-head-h": "44px",
|
|
114
|
+
"--mk-press": "0.96",
|
|
115
|
+
"--mk-composer-w": "360px",
|
|
116
|
+
"--mk-composer-r": "0"
|
|
117
|
+
};
|
|
118
|
+
const MOTION_TOKENS = {
|
|
119
|
+
"--mk-ease-surface": "cubic-bezier(0.22, 1, 0.36, 1)",
|
|
120
|
+
"--mk-ease-entrance": "cubic-bezier(0.34, 1.36, 0.64, 1)",
|
|
121
|
+
"--mk-ease-swap": "ease-in-out",
|
|
122
|
+
"--mk-ease-tooltip": "ease-out",
|
|
123
|
+
"--mk-dur-island-open": "250ms",
|
|
124
|
+
"--mk-dur-island-close": "150ms",
|
|
125
|
+
"--mk-dur-composer-open": "400ms",
|
|
126
|
+
"--mk-dur-composer-close": "350ms",
|
|
127
|
+
"--mk-dur-tooltip": "150ms",
|
|
128
|
+
"--mk-dur-swap": "150ms",
|
|
129
|
+
"--mk-dur-mark-in": "500ms",
|
|
130
|
+
"--mk-dur-fade": "150ms",
|
|
131
|
+
"--mk-delay-tooltip": "80ms",
|
|
132
|
+
"--mk-stagger-step": "40ms",
|
|
133
|
+
"--mk-stagger-cap": "240ms",
|
|
134
|
+
"--mk-scale-island": "0.97",
|
|
135
|
+
"--mk-scale-tooltip": "0.98",
|
|
136
|
+
"--mk-rise-mark": "8px",
|
|
137
|
+
"--mk-rise-card": "12px",
|
|
138
|
+
"--mk-rise-row": "6px",
|
|
139
|
+
"--mk-shift-composer": "100%",
|
|
140
|
+
"--mk-icon-scale": "0.25",
|
|
141
|
+
"--mk-icon-blur": "4px"
|
|
142
|
+
};
|
|
143
|
+
const REDUCED_MOTION_TOKENS = {
|
|
144
|
+
"--mk-ease-surface": "ease-out",
|
|
145
|
+
"--mk-ease-entrance": "ease-out",
|
|
146
|
+
"--mk-ease-swap": "ease-out",
|
|
147
|
+
"--mk-ease-tooltip": "ease-out",
|
|
148
|
+
"--mk-dur-island-open": "100ms",
|
|
149
|
+
"--mk-dur-island-close": "100ms",
|
|
150
|
+
"--mk-dur-composer-open": "100ms",
|
|
151
|
+
"--mk-dur-composer-close": "100ms",
|
|
152
|
+
"--mk-dur-tooltip": "100ms",
|
|
153
|
+
"--mk-dur-swap": "100ms",
|
|
154
|
+
"--mk-dur-mark-in": "100ms",
|
|
155
|
+
"--mk-dur-fade": "100ms",
|
|
156
|
+
"--mk-delay-tooltip": "0ms",
|
|
157
|
+
"--mk-stagger-step": "0ms",
|
|
158
|
+
"--mk-stagger-cap": "0ms",
|
|
159
|
+
"--mk-scale-island": "1",
|
|
160
|
+
"--mk-scale-tooltip": "1",
|
|
161
|
+
"--mk-rise-mark": "0px",
|
|
162
|
+
"--mk-rise-card": "0px",
|
|
163
|
+
"--mk-rise-row": "0px",
|
|
164
|
+
"--mk-shift-composer": "0%",
|
|
165
|
+
"--mk-icon-scale": "1",
|
|
166
|
+
"--mk-icon-blur": "0px"
|
|
167
|
+
};
|
|
168
|
+
const RUNTIME_TOKENS = [
|
|
169
|
+
"--mk-slot",
|
|
170
|
+
"--mk-slot-ink",
|
|
171
|
+
"--mk-pin",
|
|
172
|
+
"--mk-pin-ink",
|
|
173
|
+
"--mk-x",
|
|
174
|
+
"--mk-y",
|
|
175
|
+
"--mk-w",
|
|
176
|
+
"--mk-h"
|
|
177
|
+
];
|
|
178
|
+
const SHEET_BREAKPOINT_PX = 640;
|
|
179
|
+
//#endregion
|
|
180
|
+
export { COLOR_TOKENS, MOTION_TOKENS, RADIUS_TOKENS, REDUCED_MOTION_TOKENS, RUNTIME_TOKENS, SHADOW_TOKENS, SHEET_BREAKPOINT_PX, SIZE_TOKENS, TYPE_TOKENS };
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@maple-kit/ui",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Maple's composed reviewer parts: the marks, the island and the composer",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/maple-kit/maple.git",
|
|
11
|
+
"directory": "packages/ui"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://github.com/maple-kit/maple/tree/main/packages/ui",
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=24.0.0"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"LICENSE",
|
|
20
|
+
"NOTICE",
|
|
21
|
+
"README.md"
|
|
22
|
+
],
|
|
23
|
+
"exports": {
|
|
24
|
+
".": "./dist/index.js",
|
|
25
|
+
"./maple": "./dist/maple.js",
|
|
26
|
+
"./composer": "./dist/composer/index.js",
|
|
27
|
+
"./icons": "./dist/icons/index.js",
|
|
28
|
+
"./island": "./dist/island/index.js",
|
|
29
|
+
"./marks": "./dist/marks/index.js",
|
|
30
|
+
"./notice": "./dist/notice/index.js",
|
|
31
|
+
"./picker": "./dist/picker/index.js",
|
|
32
|
+
"./package.json": "./package.json"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@maple-kit/core": "0.1.0",
|
|
36
|
+
"@maple-kit/react": "0.1.0"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"react": "^18.2.0 || ^19.0.0",
|
|
40
|
+
"react-dom": "^18.2.0 || ^19.0.0"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/react": "19.3.0",
|
|
44
|
+
"@types/react-dom": "19.3.0",
|
|
45
|
+
"react": "19.3.0",
|
|
46
|
+
"react-dom": "19.3.0"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "tsdown && node ./scripts/size.js",
|
|
53
|
+
"clean": "rm -rf dist *.tsbuildinfo",
|
|
54
|
+
"size": "node ./scripts/size.js"
|
|
55
|
+
}
|
|
56
|
+
}
|