@ciromaciel/dashboard-kit 1.7.1 → 1.8.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ciromaciel/dashboard-kit",
3
- "version": "1.7.1",
3
+ "version": "1.8.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "The components every dashboard shares: table, empty state, loading state, destructive confirm, danger zone and wordmark.",
@@ -0,0 +1,78 @@
1
+ import { forwardRef } from 'react'
2
+ import { Text } from '@mantine/core'
3
+
4
+ /**
5
+ * The tag — the one status and label mark in every panel (14/10/2026).
6
+ *
7
+ * It came from the Blogs list (and before that from Links and Videos), where
8
+ * it is drawn as a 10px uppercase word in a hairline box. Seven panels carried
9
+ * a copy and the copies had started to drift (Newsletter's neutral ink was a
10
+ * step darker, Videos had a teal "ok"), while the Infrastructure panels drew
11
+ * the same idea with Mantine's Badge in three other ways. This is the one.
12
+ *
13
+ * neutral hairline gray.3, ink gray.6 Rascunho, Desligado, Entregue, a role
14
+ * dark filled gray.9, ink white the state that is live: Publicado, Ativo, No ar
15
+ * up hairline + green square a state MEASURED now: Verificado, Entregando
16
+ * no hairline and ink in red failure or loss: Falhou
17
+ *
18
+ * `icon` puts a 12px glyph before the word — for a state that asks for
19
+ * attention (Em revisão, Agendado, Retida). Colour is never the only signal:
20
+ * the word always says the state.
21
+ *
22
+ * Every value is a theme variable, so the tag follows light and dark mode: the
23
+ * dark tone turns into a light fill with dark ink.
24
+ */
25
+ const TONES = {
26
+ neutral: { border: 'var(--mantine-color-gray-3)', color: 'var(--mantine-color-gray-6)', background: 'transparent' },
27
+ dark: { border: 'var(--mantine-color-gray-9)', color: 'var(--mantine-color-white)', background: 'var(--mantine-color-gray-9)' },
28
+ up: { border: 'var(--mantine-color-gray-3)', color: 'var(--mantine-color-gray-7)', background: 'transparent' },
29
+ no: { border: 'var(--mantine-color-red-6)', color: 'var(--mantine-color-red-7)', background: 'transparent' },
30
+ }
31
+ // The older names the copies used.
32
+ TONES.ok = TONES.up
33
+
34
+ // forwardRef so a Tooltip can wrap it (the e-mail log explains a failure on hover).
35
+ export const Tag = forwardRef(function Tag({ tone = 'neutral', icon: Icon, children, style, ...rest }, ref) {
36
+ const look = TONES[tone] ?? TONES.neutral
37
+ return (
38
+ <Text
39
+ ref={ref}
40
+ component="span"
41
+ data-tag={tone}
42
+ display="inline-flex"
43
+ fz={10}
44
+ fw={800}
45
+ tt="uppercase"
46
+ lts="1.5px"
47
+ lh={1.5}
48
+ px={6}
49
+ py={2}
50
+ style={{
51
+ border: `1px solid ${look.border}`,
52
+ color: look.color,
53
+ background: look.background,
54
+ whiteSpace: 'nowrap',
55
+ alignItems: 'center',
56
+ gap: 4,
57
+ verticalAlign: 'middle',
58
+ ...style,
59
+ }}
60
+ {...rest}
61
+ >
62
+ {tone === 'up' || tone === 'ok' ? (
63
+ <span
64
+ aria-hidden="true"
65
+ style={{ width: 6, height: 6, background: 'var(--rlg-success)', flex: 'none' }}
66
+ />
67
+ ) : null}
68
+ {Icon ? (
69
+ <Icon
70
+ size={12}
71
+ stroke={1.5}
72
+ aria-hidden="true"
73
+ />
74
+ ) : null}
75
+ {children}
76
+ </Text>
77
+ )
78
+ })
package/src/index.js CHANGED
@@ -62,6 +62,7 @@ export { DeleteModal, deleteTitleScale } from './components/DeleteModal'
62
62
  // one button; the inventory and the backup live in the modal.
63
63
  export { DangerZone } from './components/DangerZone'
64
64
  export { ZenLabel } from './components/ZenLabel'
65
+ export { Tag } from './components/Tag'
65
66
  export { notify } from './components/notify'
66
67
  export { NOTIFICATIONS_PROPS, NOTIFY_DESCRIPTION_CSS, notificationTheme } from './components/notify-theme'
67
68
  export { panelTheme } from './theme'
package/src/theme.js CHANGED
@@ -165,14 +165,14 @@ export const panelTheme = createTheme({
165
165
  Menu: {
166
166
  defaultProps: { shadow: 'none', width: 210, withinPortal: true, radius: 0 },
167
167
  styles: theme => ({
168
- dropdown: { border: `1px solid ${theme.colors.gray[2]}` },
168
+ dropdown: { border: `1px solid var(--mantine-color-gray-2)` },
169
169
  item: { fontSize: rem(13), fontWeight: 500 },
170
170
  label: { fontSize: rem(10), fontWeight: 800, textTransform: 'uppercase', letterSpacing: '1.5px' },
171
171
  }),
172
172
  },
173
173
  Popover: {
174
174
  defaultProps: { shadow: 'none', radius: 0 },
175
- styles: theme => ({ dropdown: { border: `1px solid ${theme.colors.gray[2]}` } }),
175
+ styles: theme => ({ dropdown: { border: `1px solid var(--mantine-color-gray-2)` } }),
176
176
  },
177
177
 
178
178
  // --- DATA ---
@@ -192,11 +192,11 @@ export const panelTheme = createTheme({
192
192
  fontWeight: 800,
193
193
  textTransform: 'uppercase',
194
194
  letterSpacing: '1.5px',
195
- color: theme.colors.gray[5],
196
- borderBottom: `1px solid ${theme.colors.gray[2]}`,
195
+ color: "var(--mantine-color-gray-5)",
196
+ borderBottom: `1px solid var(--mantine-color-gray-2)`,
197
197
  whiteSpace: 'nowrap',
198
198
  },
199
- td: { borderBottom: `1px solid ${theme.colors.gray[2]}`, fontSize: rem(13), color: theme.colors.gray[7] },
199
+ td: { borderBottom: `1px solid var(--mantine-color-gray-2)`, fontSize: rem(13), color: "var(--mantine-color-gray-7)" },
200
200
  }),
201
201
  },
202
202
  Badge: {
@@ -272,7 +272,7 @@ export const panelTheme = createTheme({
272
272
  defaultProps: { size: 'sm', radius: '0', inputWrapperOrder: ['label', 'input', 'description', 'error'] },
273
273
  styles: (theme, props) => ({
274
274
  label: { marginBottom: rem(6), fontWeight: 700, fontSize: rem(13) },
275
- input: props.variant === 'unstyled' ? {} : { border: `1px solid ${theme.colors.gray[2]}` },
275
+ input: props.variant === 'unstyled' ? {} : { border: `1px solid var(--mantine-color-gray-2)` },
276
276
  }),
277
277
  },
278
278
  /**
@@ -290,35 +290,35 @@ export const panelTheme = createTheme({
290
290
  defaultProps: { size: 'sm', radius: '0', inputWrapperOrder: ['label', 'input', 'description', 'error'] },
291
291
  styles: (theme, props) => ({
292
292
  label: { marginBottom: rem(6), fontWeight: 700, fontSize: rem(13) },
293
- input: props.variant === 'unstyled' ? {} : { border: `1px solid ${theme.colors.gray[2]}` },
293
+ input: props.variant === 'unstyled' ? {} : { border: `1px solid var(--mantine-color-gray-2)` },
294
294
  }),
295
295
  },
296
296
  Textarea: {
297
297
  defaultProps: { size: 'sm', radius: '0', inputWrapperOrder: ['label', 'input', 'description', 'error'] },
298
298
  styles: (theme, props) => ({
299
299
  label: { marginBottom: rem(6), fontWeight: 700, fontSize: rem(13) },
300
- input: props.variant === 'unstyled' ? {} : { border: `1px solid ${theme.colors.gray[2]}` },
300
+ input: props.variant === 'unstyled' ? {} : { border: `1px solid var(--mantine-color-gray-2)` },
301
301
  }),
302
302
  },
303
303
  Select: {
304
304
  defaultProps: { size: 'sm', radius: '0', inputWrapperOrder: ['label', 'input', 'description', 'error'] },
305
305
  styles: (theme, props) => ({
306
306
  label: { marginBottom: rem(6), fontWeight: 700, fontSize: rem(13) },
307
- input: props.variant === 'unstyled' ? {} : { border: `1px solid ${theme.colors.gray[2]}` },
307
+ input: props.variant === 'unstyled' ? {} : { border: `1px solid var(--mantine-color-gray-2)` },
308
308
  }),
309
309
  },
310
310
  NumberInput: {
311
311
  defaultProps: { size: 'sm', radius: '0', inputWrapperOrder: ['label', 'input', 'description', 'error'] },
312
312
  styles: theme => ({
313
313
  label: { marginBottom: rem(6), fontWeight: 700, fontSize: rem(13) },
314
- input: { border: `1px solid ${theme.colors.gray[2]}` },
314
+ input: { border: `1px solid var(--mantine-color-gray-2)` },
315
315
  }),
316
316
  },
317
317
  Autocomplete: {
318
318
  defaultProps: { size: 'sm', radius: '0', inputWrapperOrder: ['label', 'input', 'description', 'error'] },
319
319
  styles: theme => ({
320
320
  label: { marginBottom: rem(6), fontWeight: 700, fontSize: rem(13) },
321
- input: { border: `1px solid ${theme.colors.gray[2]}` },
321
+ input: { border: `1px solid var(--mantine-color-gray-2)` },
322
322
  }),
323
323
  },
324
324
  /**
@@ -343,7 +343,7 @@ export const panelTheme = createTheme({
343
343
  styles: theme => ({
344
344
  label: { marginBottom: rem(6), fontWeight: 700, fontSize: rem(13) },
345
345
  input: {
346
- border: `1px solid ${theme.colors.gray[2]}`,
346
+ border: `1px solid var(--mantine-color-gray-2)`,
347
347
  minHeight: rem(36),
348
348
  display: 'flex',
349
349
  alignItems: 'center',
@@ -356,7 +356,7 @@ export const panelTheme = createTheme({
356
356
  defaultProps: { size: 'sm', radius: '0', inputWrapperOrder: ['label', 'input', 'description', 'error'] },
357
357
  styles: theme => ({
358
358
  label: { marginBottom: rem(6), fontWeight: 700, fontSize: rem(13) },
359
- input: { border: `1px solid ${theme.colors.gray[2]}` },
359
+ input: { border: `1px solid var(--mantine-color-gray-2)` },
360
360
  }),
361
361
  },
362
362
  SegmentedControl: {
@@ -381,10 +381,10 @@ export const panelTheme = createTheme({
381
381
  fontFamily: 'var(--mantine-font-family-monospace)',
382
382
  fontSize: rem(10),
383
383
  fontWeight: 700,
384
- color: theme.colors.gray[5],
384
+ color: "var(--mantine-color-gray-5)",
385
385
  backgroundColor: theme.white,
386
- border: `1px solid ${theme.colors.gray[2]}`,
387
- borderBottomColor: theme.colors.gray[2],
386
+ border: `1px solid var(--mantine-color-gray-2)`,
387
+ borderBottomColor: "var(--mantine-color-gray-2)",
388
388
  boxShadow: 'none',
389
389
  borderRadius: 0,
390
390
  },