@nexxtmove/ui 1.53.0 → 1.54.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/dist/ui.css CHANGED
@@ -1,2 +1,3 @@
1
- input[data-snap][data-v-5d3904ac]{animation:snap-in-5d3904ac .18s var(--ease-out-strong)}input[data-snap=up][data-v-5d3904ac]{--snap-from:2px}input[data-snap=down][data-v-5d3904ac]{--snap-from:-2px}@keyframes snap-in-5d3904ac{0%{opacity:0;transform:translateY(var(--snap-from))}to{opacity:1;transform:translateY(0)}}@media (prefers-reduced-motion:reduce){input[data-snap][data-v-5d3904ac]{animation:1ms snap-hold-5d3904ac}@keyframes snap-hold-5d3904ac{0%,to{opacity:1}}}input[data-snap][data-v-15feed8b]{animation:snap-in-15feed8b .18s var(--ease-out-strong)}input[data-snap=up][data-v-15feed8b]{--snap-from:2px}input[data-snap=down][data-v-15feed8b]{--snap-from:-2px}@keyframes snap-in-15feed8b{0%{opacity:0;transform:translateY(var(--snap-from))}to{opacity:1;transform:translateY(0)}}@media (prefers-reduced-motion:reduce){input[data-snap][data-v-15feed8b]{animation:1ms snap-hold-15feed8b}@keyframes snap-hold-15feed8b{0%,to{opacity:1}}}rect[data-v-0a5d9b21]{animation-duration:4s;animation-timing-function:cubic-bezier(.77,0,.175,1);animation-iteration-count:infinite}rect[data-v-0a5d9b21]:first-child{animation-name:load-1-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(2){animation-name:load-2-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(3){animation-name:load-3-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(4){animation-name:load-4-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(5){animation-name:load-5-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(6){animation-name:load-6-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(7){animation-name:load-7-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(8){animation-name:load-8-0a5d9b21}@media (prefers-reduced-motion:reduce){rect[data-v-0a5d9b21]{animation:none}svg[data-v-0a5d9b21]{animation:2.5s ease-in-out infinite pulse-0a5d9b21}}@keyframes pulse-0a5d9b21{0%,to{opacity:1}50%{opacity:.65}}@keyframes load-1-0a5d9b21{0%,80%{transform:translate(0)}5%,20%,60%,75%{transform:translate(-25px,25px)}30%,50%{transform:translate(-75px,75px)}}@keyframes load-2-0a5d9b21{5%,75%{transform:translate(0%)}10%,20%,60%,70%{transform:translate(50px)}30%,50%{transform:translateY(50px)}}@keyframes load-3-0a5d9b21{10%,70%{transform:translate(0%)}15%,65%{transform:translateY(-50px)}20%,60%{fill:var(--color-sapphire-500);transform:translateY(-50px)}30%,50%{fill:var(--color-purple-500);transform:translate(-50px)}}@keyframes load-4-0a5d9b21{20%,60%{transform:translate(0%)}30%,50%{transform:translate(50px,-50px)}}@keyframes load-5-0a5d9b21{0%,80%{transform:translate(0%)}5%,20%,60%,75%{transform:translateY(50px)}30%,50%{transform:translate(50px)}}@keyframes load-6-0a5d9b21{5%,75%{transform:translate(0%)}10%,20%,60%,70%{transform:translate(-50px)}30%,50%{transform:translateY(-50px)}}@keyframes load-7-0a5d9b21{10%,70%{transform:translate(0%)}15%,20%,60%,65%{transform:translate(50px)}30%,50%{transform:translate(100px,-50px)}}@keyframes load-8-0a5d9b21{15%,65%{transform:translate(0%)}20%,60%{transform:translateY(-50px)}30%,50%{transform:translate(50px,-100px)}}.timer-circle[data-v-7e3c5bda]{stroke-dashoffset:0;animation:linear forwards toast-timer-7e3c5bda}@keyframes toast-timer-7e3c5bda{to{stroke-dashoffset:var(--fa0d20de)}}
1
+ /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){[data-v-add2fbaf],[data-v-add2fbaf]:before,[data-v-add2fbaf]:after,[data-v-add2fbaf]::backdrop{--tw-font-weight:initial}}}@layer components{[role=img][data-v-add2fbaf]{height:fit-content;font-family:var(--font-sans,"Poppins", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-size:var(--text-xs,.75rem);line-height:var(--tw-leading,var(--text-xs--line-height,calc(1 / .75)));--tw-font-weight:var(--font-weight-semibold,600);font-weight:var(--font-weight-semibold,600);border-top-left-radius:.333333em;border-bottom-left-radius:.333333em;margin-right:calc(.5lh + .333333em);padding-block:.333333em;padding-inline:.666667em}}@property --tw-font-weight{syntax:"*";inherits:false}input[data-snap][data-v-5d3904ac]{animation:snap-in-5d3904ac .18s var(--ease-out-strong)}input[data-snap=up][data-v-5d3904ac]{--snap-from:2px}input[data-snap=down][data-v-5d3904ac]{--snap-from:-2px}@keyframes snap-in-5d3904ac{0%{opacity:0;transform:translateY(var(--snap-from))}to{opacity:1;transform:translateY(0)}}@media (prefers-reduced-motion:reduce){input[data-snap][data-v-5d3904ac]{animation:1ms snap-hold-5d3904ac}@keyframes snap-hold-5d3904ac{0%,to{opacity:1}}}input[data-snap][data-v-15feed8b]{animation:snap-in-15feed8b .18s var(--ease-out-strong)}input[data-snap=up][data-v-15feed8b]{--snap-from:2px}input[data-snap=down][data-v-15feed8b]{--snap-from:-2px}@keyframes snap-in-15feed8b{0%{opacity:0;transform:translateY(var(--snap-from))}to{opacity:1;transform:translateY(0)}}@media (prefers-reduced-motion:reduce){input[data-snap][data-v-15feed8b]{animation:1ms snap-hold-15feed8b}@keyframes snap-hold-15feed8b{0%,to{opacity:1}}}rect[data-v-0a5d9b21]{animation-duration:4s;animation-timing-function:cubic-bezier(.77,0,.175,1);animation-iteration-count:infinite}rect[data-v-0a5d9b21]:first-child{animation-name:load-1-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(2){animation-name:load-2-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(3){animation-name:load-3-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(4){animation-name:load-4-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(5){animation-name:load-5-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(6){animation-name:load-6-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(7){animation-name:load-7-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(8){animation-name:load-8-0a5d9b21}@media (prefers-reduced-motion:reduce){rect[data-v-0a5d9b21]{animation:none}svg[data-v-0a5d9b21]{animation:2.5s ease-in-out infinite pulse-0a5d9b21}}@keyframes pulse-0a5d9b21{0%,to{opacity:1}50%{opacity:.65}}@keyframes load-1-0a5d9b21{0%,80%{transform:translate(0)}5%,20%,60%,75%{transform:translate(-25px,25px)}30%,50%{transform:translate(-75px,75px)}}@keyframes load-2-0a5d9b21{5%,75%{transform:translate(0%)}10%,20%,60%,70%{transform:translate(50px)}30%,50%{transform:translateY(50px)}}@keyframes load-3-0a5d9b21{10%,70%{transform:translate(0%)}15%,65%{transform:translateY(-50px)}20%,60%{fill:var(--color-sapphire-500);transform:translateY(-50px)}30%,50%{fill:var(--color-purple-500);transform:translate(-50px)}}@keyframes load-4-0a5d9b21{20%,60%{transform:translate(0%)}30%,50%{transform:translate(50px,-50px)}}@keyframes load-5-0a5d9b21{0%,80%{transform:translate(0%)}5%,20%,60%,75%{transform:translateY(50px)}30%,50%{transform:translate(50px)}}@keyframes load-6-0a5d9b21{5%,75%{transform:translate(0%)}10%,20%,60%,70%{transform:translate(-50px)}30%,50%{transform:translateY(-50px)}}@keyframes load-7-0a5d9b21{10%,70%{transform:translate(0%)}15%,20%,60%,65%{transform:translate(50px)}30%,50%{transform:translate(100px,-50px)}}@keyframes load-8-0a5d9b21{15%,65%{transform:translate(0%)}20%,60%{transform:translateY(-50px)}30%,50%{transform:translate(50px,-100px)}}.timer-circle[data-v-7e3c5bda]{stroke-dashoffset:0;animation:linear forwards toast-timer-7e3c5bda}@keyframes toast-timer-7e3c5bda{to{stroke-dashoffset:var(--fa0d20de)}}
2
3
  /*$vite$:1*/
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nexxtmove/ui",
3
3
  "type": "module",
4
- "version": "1.53.0",
4
+ "version": "1.54.0",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./dist/index.d.ts",
@@ -1,14 +1,14 @@
1
- <script lang="ts" setup>
2
- import { computed } from 'vue'
3
-
1
+ <script lang="ts">
2
+ /** An energy-label grade, from `A++++` down to `G`. */
4
3
  export type EnergyLabelLetter =
5
4
  'A++++' | 'A+++' | 'A++' | 'A+' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G'
6
5
 
7
- interface NexxtEnergyLabelProps {
8
- label: EnergyLabelLetter | Lowercase<EnergyLabelLetter>
9
- }
10
-
11
- const COLORS: Record<EnergyLabelLetter, string> = {
6
+ /**
7
+ * The swatch colour per grade, as an uppercase hex string. Every `A` grade
8
+ * shares one green. Key order runs from best to worst, so
9
+ * `Object.keys(ENERGY_LABEL_COLORS)` lists the grades in display order.
10
+ */
11
+ export const ENERGY_LABEL_COLORS: Readonly<Record<EnergyLabelLetter, string>> = Object.freeze({
12
12
  'A++++': '#00953F',
13
13
  'A+++': '#00953F',
14
14
  'A++': '#00953F',
@@ -20,7 +20,22 @@ const COLORS: Record<EnergyLabelLetter, string> = {
20
20
  E: '#F9A93C',
21
21
  F: '#EF7D34',
22
22
  G: '#E63329',
23
+ })
24
+
25
+ /**
26
+ * Size, padding, margin and typography follow from classes on the component:
27
+ * a font-size class scales the whole label, arrow included. The arrow always
28
+ * takes the label's full height. When you raise the vertical padding, raise
29
+ * the right margin by the same amount so the arrow keeps its room.
30
+ */
31
+ export interface NexxtEnergyLabelProps {
32
+ /** The grade to show. Lowercase input is accepted and shown in uppercase. */
33
+ label: EnergyLabelLetter | Lowercase<EnergyLabelLetter>
23
34
  }
35
+ </script>
36
+
37
+ <script lang="ts" setup>
38
+ import { computed } from 'vue'
24
39
 
25
40
  defineOptions({
26
41
  name: 'NexxtEnergyLabel',
@@ -30,16 +45,41 @@ const { label } = defineProps<NexxtEnergyLabelProps>()
30
45
 
31
46
  const normalized = computed(() => label.toUpperCase() as EnergyLabelLetter)
32
47
 
33
- const color = computed(() => COLORS[normalized.value])
48
+ const color = computed(() => ENERGY_LABEL_COLORS[normalized.value])
34
49
  </script>
35
50
 
36
51
  <template>
37
52
  <span
38
53
  role="img"
39
54
  :aria-label="`Energielabel ${normalized}`"
40
- class="relative isolate mr-3 inline-flex h-6 items-center justify-center rounded-l px-2 extra-small-semibold text-white after:absolute after:top-1/2 after:left-full after:size-4.25 after:-translate-1/2 after:rotate-45 after:rounded-tr after:bg-(--energy-label-color) after:content-['']"
55
+ class="relative isolate inline-flex items-center justify-center text-white after:absolute after:top-1/2 after:left-full after:aspect-square after:h-[calc(100%*17/24)] after:-translate-1/2 after:rotate-45 after:rounded-tr-[calc(100%*4/17)] after:bg-(--energy-label-color) after:content-['']"
41
56
  :style="{ backgroundColor: color, '--energy-label-color': color }"
42
57
  >
43
58
  <span aria-hidden="true" class="relative z-10">{{ normalized }}</span>
44
59
  </span>
45
60
  </template>
61
+
62
+ <style scoped>
63
+ @reference '../../../index.css';
64
+
65
+ /*
66
+ * The sizing defaults sit in the components layer, below Tailwind's utilities,
67
+ * so padding, margin, radius and typography classes on the component win
68
+ * without `!`. They are in `em` and `lh`, so a font-size class scales the whole
69
+ * label; at the default 12px/16px they come out at the old h-6, px-2, mr-3 and
70
+ * rounded-l. The margin is half the label's height: the room the arrow takes.
71
+ * h-fit stands in for the old fixed h-6: a stretching flex or grid parent
72
+ * must not pull the label (and its arrow) taller. The root is matched by its
73
+ * role, as a class name trips the Tailwind lint.
74
+ *
75
+ * The arrow is a square of 17/24 of the label's height, turned 45 degrees, so
76
+ * its diagonal just covers the height (no seam) and its tip sits half a height
77
+ * past the edge. 17/24 and the 4/17 corner are the old 17px square with its
78
+ * 4px corner on a 24px label, kept as ratios.
79
+ */
80
+ @layer components {
81
+ [role='img'] {
82
+ @apply mr-[calc(0.5lh+1em/3)] h-fit rounded-l-[calc(1em/3)] px-[calc(2em/3)] py-[calc(1em/3)] extra-small-semibold;
83
+ }
84
+ }
85
+ </style>
package/src/index.ts CHANGED
@@ -9,6 +9,7 @@ export type {
9
9
  TimelinePhase,
10
10
  TimelineResponse,
11
11
  } from './components/molecules/TimelineEvent/TimelineTypes'
12
+ export { ENERGY_LABEL_COLORS } from './components/atoms/EnergyLabel/EnergyLabel.vue'
12
13
  export type { EnergyLabelLetter } from './components/atoms/EnergyLabel/EnergyLabel.vue'
13
14
  export type { IconType, NexxtIconName } from './components/atoms/Icon/Icon.vue'
14
15
  export type { CustomIconName } from './components/atoms/Icon/customIcons'
package/src/nuxt.ts CHANGED
@@ -144,8 +144,12 @@ const module: NuxtModule<ModuleOptions> = defineNuxtModule<ModuleOptions>({
144
144
 
145
145
  // Compiled component `<style>` blocks (scoped rules, keyframes). Not
146
146
  // covered by the Tailwind entry above — that only scans the .vue source
147
- // for class names. Pushed last so it stays unlayered and wins over
148
- // Tailwind's layers.
147
+ // for class names. Pushed after the Tailwind entry on purpose. Most rules
148
+ // are unlayered and beat Tailwind's layers, but EnergyLabel puts its
149
+ // sizing defaults in `@layer components`, so that classes passed to the
150
+ // component can override them. Because `@import "tailwindcss"` loads
151
+ // first, the layer order is already theme, base, components, utilities,
152
+ // and utilities win.
149
153
  const componentCSS = resolve('./ui.css')
150
154
 
151
155
  if (existsSync(componentCSS) && !hasComponentCSS(nuxt.options.css, componentCSS)) {