@wishbone-media/spark 0.19.0 → 0.21.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.
@@ -0,0 +1,97 @@
1
+ import { icon } from '@fortawesome/fontawesome-svg-core'
2
+
3
+ /**
4
+ * Spark Boolean Renderer
5
+ *
6
+ * Renders boolean-like values as check/times icons in a circular container
7
+ *
8
+ * Truthy values: true, 1, '1', 'yes', 'true'
9
+ * Falsy values: false, 0, '0', 'no', 'false', null, undefined, ''
10
+ *
11
+ * Usage:
12
+ * {
13
+ * data: 'is_active',
14
+ * renderer: 'spark.boolean',
15
+ * rendererConfig: {
16
+ * trueIcon: 'check', // Default: 'check'
17
+ * falseIcon: 'xmark', // Default: 'xmark'
18
+ * trueColor: 'green', // Default: 'green'
19
+ * falseColor: 'red', // Default: 'red'
20
+ * size: 32, // Default: 32 (px)
21
+ * iconPrefix: 'far' // Default: 'far' (solid)
22
+ * }
23
+ * }
24
+ */
25
+
26
+ const colorClasses = {
27
+ green: { bg: 'bg-green-100', text: 'text-green-500' },
28
+ red: { bg: 'bg-red-100', text: 'text-red-500' },
29
+ yellow: { bg: 'bg-yellow-100', text: 'text-yellow-500' },
30
+ blue: { bg: 'bg-blue-100', text: 'text-blue-500' },
31
+ gray: { bg: 'bg-gray-100', text: 'text-gray-500' },
32
+ purple: { bg: 'bg-purple-100', text: 'text-purple-500' },
33
+ }
34
+
35
+ /**
36
+ * Determines if a value is truthy in the context of boolean display
37
+ * @param {*} value - The value to check
38
+ * @returns {boolean}
39
+ */
40
+ const isTruthy = (value) => {
41
+ if (value === null || value === undefined || value === '') {
42
+ return false
43
+ }
44
+ if (typeof value === 'boolean') {
45
+ return value
46
+ }
47
+ if (typeof value === 'number') {
48
+ return value === 1
49
+ }
50
+ if (typeof value === 'string') {
51
+ const normalized = value.toLowerCase().trim()
52
+ return normalized === '1' || normalized === 'yes' || normalized === 'true'
53
+ }
54
+ return false
55
+ }
56
+
57
+ export const booleanRenderer = (sparkTable) => {
58
+ return (instance, td, row, col, prop, value, cellProperties) => {
59
+ // Clear cell
60
+ td.innerHTML = ''
61
+ td.classList.add('spark-table-cell-boolean')
62
+
63
+ const config = cellProperties.rendererConfig || {}
64
+
65
+ const truthy = isTruthy(value)
66
+ const iconName = truthy ? (config.trueIcon || 'check') : (config.falseIcon || 'xmark')
67
+ const colorName = truthy ? (config.trueColor || 'green') : (config.falseColor || 'red')
68
+ const size = config.size || 32
69
+ const iconPrefix = config.iconPrefix || 'far'
70
+
71
+ const colors = colorClasses[colorName] || colorClasses.gray
72
+
73
+ // Create circular container
74
+ const container = document.createElement('div')
75
+ container.classList.add(
76
+ 'inline-flex',
77
+ 'items-center',
78
+ 'justify-center',
79
+ 'rounded-full',
80
+ colors.bg,
81
+ colors.text,
82
+ )
83
+ container.style.width = `${size}px`
84
+ container.style.height = `${size}px`
85
+
86
+ // Create icon
87
+ const iconElement = document.createElement('span')
88
+ iconElement.innerHTML = icon({ prefix: iconPrefix, iconName }).html
89
+ iconElement.classList.add('flex', 'items-center', 'justify-center')
90
+ // Icon size is roughly 50% of container
91
+ const iconSize = Math.round(size * 0.5)
92
+ iconElement.style.fontSize = `${iconSize}px`
93
+
94
+ container.appendChild(iconElement)
95
+ td.appendChild(container)
96
+ }
97
+ }
@@ -1,6 +1,7 @@
1
1
  import { baseRenderer, registerRenderer } from 'handsontable/renderers'
2
2
  import { actionsRenderer } from './actions.js'
3
3
  import { badgeRenderer } from './badge.js'
4
+ import { booleanRenderer } from './boolean.js'
4
5
  import { linkRenderer } from './link.js'
5
6
  import { imageRenderer } from './image.js'
6
7
  import { dateRenderer } from './date.js'
@@ -50,6 +51,7 @@ export const getRenderer = (key) => {
50
51
  * Registers the following renderers:
51
52
  * - spark.actions: Inline action buttons
52
53
  * - spark.badge: Colored status badges
54
+ * - spark.boolean: Boolean indicators with check/times icons
53
55
  * - spark.link: Clickable links (email, phone, custom)
54
56
  * - spark.image: Image thumbnails
55
57
  * - spark.date: Formatted dates
@@ -61,6 +63,7 @@ export const registerSparkRenderers = (sparkTable) => {
61
63
  // Register Spark renderers
62
64
  register('spark.actions', actionsRenderer(sparkTable))
63
65
  register('spark.badge', badgeRenderer(sparkTable))
66
+ register('spark.boolean', booleanRenderer(sparkTable))
64
67
  register('spark.link', linkRenderer(sparkTable))
65
68
  register('spark.image', imageRenderer(sparkTable))
66
69
  register('spark.date', dateRenderer(sparkTable))