siam-ui-utils 2.2.10 → 2.2.12

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/eslint.config.mjs CHANGED
@@ -17,6 +17,10 @@ export default defineConfig([
17
17
  ecmaFeatures: { jsx: true },
18
18
  },
19
19
  },
20
+ parser: '@typescript-eslint/parser',
21
+ parserOptions: {
22
+ ecmaVersion: 'latest',
23
+ },
20
24
  plugins: {
21
25
  react: pluginReact,
22
26
  'react-hooks': pluginReactHooks,
package/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { ItemSlot } from './src/view-layout/item-slot';
2
+
1
3
  declare module 'siam-ui-utils' {
2
4
  //BRIDGES
3
5
  export function withRouter(props);
@@ -85,4 +87,7 @@ declare module 'siam-ui-utils' {
85
87
 
86
88
  //COPY LINK
87
89
  export function CopyLink(props);
90
+
91
+ //VIEW LAYOUT
92
+ export function ViewLayout(props);
88
93
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "siam-ui-utils",
3
- "version": "2.2.10",
3
+ "version": "2.2.12",
4
4
  "keywords": [
5
5
  "ampf-react",
6
6
  "ampf-utils",
@@ -50,14 +50,16 @@
50
50
  "@types/react": "^18.3.3",
51
51
  "@types/react-dom": "^18.3.0",
52
52
  "@types/react-router-dom": "^5.3.3",
53
+ "@typescript-eslint/parser": "^8.42.0",
53
54
  "@vitejs/plugin-react": "^4.3.1",
54
55
  "copyfiles": "^2.4.1",
55
- "eslint": "^9.31.0",
56
+ "eslint": "^9.35.0",
56
57
  "eslint-plugin-react": "^7.37.5",
57
58
  "eslint-plugin-react-hooks": "^5.2.0",
58
59
  "eslint-plugin-react-refresh": "^0.4.20",
59
60
  "globals": "^16.3.0",
60
61
  "sass-embedded": "^1.79.4",
62
+ "typescript": "^5.5.3",
61
63
  "typescript-eslint": "^8.38.0",
62
64
  "vite": "^7.0.1",
63
65
  "vitest": "^3.2.4"
package/src/App.jsx CHANGED
@@ -11,8 +11,26 @@ import './index.css';
11
11
  import './App.css';
12
12
  import './assets/css/vendor/bootstrap.min.css';
13
13
  import { WhereByRoom } from './where-by-room';
14
+ import ViewLayout from './view-layout';
14
15
  import CopyLink from './copy-link';
15
16
 
17
+ const slots = [
18
+ {
19
+ slot: 1,
20
+ x: 3,
21
+ y: 3,
22
+ w: 2,
23
+ h: 2,
24
+ legend: 'Prueba',
25
+ direction: 'column',
26
+ contentSize: 'medium',
27
+ align: 'stretch',
28
+ justify: 'flex-start',
29
+ component: null,
30
+ showBorder: true,
31
+ },
32
+ ];
33
+
16
34
  const App = () => {
17
35
  const [open, setOpen] = useState('0');
18
36
  const toggle = (id) => {
@@ -112,11 +130,17 @@ const App = () => {
112
130
  </AccordionBody>
113
131
  </AccordionItem>
114
132
  <AccordionItem>
115
- <AccordionHeader targetId="2">Copy-Link</AccordionHeader>
116
- <AccordionBody accordionId="2">
133
+ <AccordionHeader targetId="6">Copy-Link</AccordionHeader>
134
+ <AccordionBody accordionId="6">
117
135
  <CopyLink link="https://linkdepruebaparaelcopylink.com" />
118
136
  </AccordionBody>
119
137
  </AccordionItem>
138
+ <AccordionItem>
139
+ <AccordionHeader targetId="7">Reusable ViewLayout</AccordionHeader>
140
+ <AccordionBody accordionId="7">
141
+ <ViewLayout slots={slots} />
142
+ </AccordionBody>
143
+ </AccordionItem>
120
144
  </Accordion>
121
145
  </div>
122
146
  );
package/src/index.js CHANGED
@@ -8,3 +8,4 @@ export * from './tomar-foto';
8
8
  export * as IntlMessages from './IntlMessages';
9
9
  export * from './where-by-room';
10
10
  export * from './copy-link';
11
+ export * from './view-layout';
@@ -0,0 +1,18 @@
1
+ import './styles.scss';
2
+
3
+ const ButtonEditor = ({ activo, onClick }) => (
4
+ <button
5
+ className={`visualizador-editor-btn ${
6
+ activo
7
+ ? 'visualizador-editor-btn--activo'
8
+ : 'visualizador-editor-btn--inactivo'
9
+ }`}
10
+ onClick={onClick}
11
+ >
12
+ <span>
13
+ <i className="icon-eye" />
14
+ </span>
15
+ </button>
16
+ );
17
+
18
+ export default ButtonEditor;
@@ -0,0 +1,7 @@
1
+ export const GRID_SIZES = {
2
+ sm: { cols: 18, rows: 18 },
3
+ md: { cols: 12, rows: 12 },
4
+ lg: { cols: 6, rows: 6 },
5
+ };
6
+
7
+ export const VERSION = import.meta?.env?.REACT_APP_VERSION || 'TLBD';
@@ -0,0 +1,27 @@
1
+ import './styles.scss';
2
+
3
+ const EditorLayer = ({ gridCols, gridRows }) => {
4
+ return (
5
+ <div
6
+ className="editor-layer"
7
+ style={{
8
+ gridTemplateColumns: `repeat(${gridCols}, 1fr)`,
9
+ gridTemplateRows: `repeat(${gridRows}, 1fr)`,
10
+ }}
11
+ >
12
+ {Array.from({ length: gridRows * gridCols }).map((_, idx) => {
13
+ const x = idx % gridCols;
14
+ const y = Math.floor(idx / gridCols);
15
+ return (
16
+ <div key={`cell-${x}-${y}`} className="editor-layer-cell">
17
+ <div className="editor-layer-cell-coord">
18
+ x:{x};y:{y}
19
+ </div>
20
+ </div>
21
+ );
22
+ })}
23
+ </div>
24
+ );
25
+ };
26
+
27
+ export default EditorLayer;
@@ -0,0 +1,59 @@
1
+ import React, { FC, useState } from 'react';
2
+ import SlotWrapper from './slot-wrapper';
3
+ import { ItemSlot } from './item-slot';
4
+ import EditorLayer from './editor-layer.jsx';
5
+ import { GRID_SIZES, VERSION } from './constants';
6
+ import ButtonEditor from './button-editor.jsx';
7
+ import './styles.scss';
8
+
9
+ interface LayoutProps {
10
+ slots: ItemSlot[];
11
+ alto?: number;
12
+ ancho?: number;
13
+ size?: 'sm' | 'md' | 'lg';
14
+ [key: string]: any;
15
+ }
16
+
17
+ const ViewLayout: FC<LayoutProps> = ({
18
+ slots = [],
19
+ size = 'md',
20
+ alto = 80,
21
+ ancho = 90,
22
+ ...props
23
+ }) => {
24
+ const isVersionLetters = /^[A-Za-z]+$/.test(VERSION);
25
+ const [isEditorActivo, setEditorActivo] = useState(false);
26
+ const gridCols = GRID_SIZES[size].cols;
27
+ const gridRows = GRID_SIZES[size].rows;
28
+ return (
29
+ <div className="visualizador-container">
30
+ {isVersionLetters && (
31
+ <ButtonEditor
32
+ activo={isEditorActivo}
33
+ onClick={() => setEditorActivo((prev) => !prev)}
34
+ />
35
+ )}
36
+
37
+ <div
38
+ className="visualizador-grid-css"
39
+ style={{
40
+ maxWidth: `${ancho}vw`,
41
+ height: `${alto}vh`,
42
+ gridTemplateColumns: `repeat(${gridCols}, 1fr)`,
43
+ gridTemplateRows: `repeat(${gridRows}, 1fr)`,
44
+ }}
45
+ {...props}
46
+ >
47
+ {isEditorActivo && (
48
+ <EditorLayer gridCols={gridCols} gridRows={gridRows} />
49
+ )}
50
+ {slots.map((slot) => {
51
+ const { x, y, w, h, legend } = slot;
52
+ return <SlotWrapper {...slot} legend={legend} key={slot.slot} />;
53
+ })}
54
+ </div>
55
+ </div>
56
+ );
57
+ };
58
+
59
+ export default ViewLayout;
@@ -0,0 +1,20 @@
1
+ export interface ItemSlot {
2
+ slot: number;
3
+ component: React.ReactElement;
4
+ x: number;
5
+ y: number;
6
+ w?: number;
7
+ h?: number;
8
+ align?: 'start' | 'center' | 'end' | 'stretch';
9
+ contentSize?: 'small' | 'medium' | 'large';
10
+ direction?: 'row' | 'column';
11
+ justify?:
12
+ | 'start'
13
+ | 'center'
14
+ | 'end'
15
+ | 'space-between'
16
+ | 'space-around'
17
+ | 'space-evenly';
18
+ legend?: string;
19
+ showBorder?: boolean;
20
+ }
@@ -0,0 +1,44 @@
1
+ import React, { FC } from 'react';
2
+ import { ItemSlot } from './item-slot';
3
+
4
+ const SlotWrapper: FC<ItemSlot> = ({
5
+ slot = 1,
6
+ component = null,
7
+ x = 0,
8
+ y = 0,
9
+ w = 2,
10
+ h = 2,
11
+ align = 'stretch',
12
+ contentSize = 'medium',
13
+ direction = 'column',
14
+ justify = 'flex-start',
15
+ legend,
16
+ showBorder = false,
17
+ }) => {
18
+ return (
19
+ <fieldset
20
+ key={slot}
21
+ className={
22
+ `visualizador-slot ` +
23
+ `visualizador-slot-content--${contentSize} ` +
24
+ `visualizador-slot--${direction} ` +
25
+ `visualizador-slot-align--${align} ` +
26
+ `visualizador-slot-justify--${justify} ` +
27
+ (!showBorder ? 'visualizador-slot--no-border' : '')
28
+ }
29
+ style={{
30
+ position: 'relative',
31
+ gridColumn: `${x + 1} / span ${w}`,
32
+ gridRow: `${y + 1} / span ${h}`,
33
+ display: 'flex',
34
+ overflow: 'hidden',
35
+ border: showBorder ? undefined : 'none',
36
+ }}
37
+ >
38
+ <legend className="slot-legend">{legend}</legend>
39
+ <div className="slot-content">{component}</div>
40
+ </fieldset>
41
+ );
42
+ };
43
+
44
+ export default SlotWrapper;
@@ -0,0 +1,143 @@
1
+ // Container
2
+ .visualizador-container {
3
+ position: relative;
4
+ }
5
+
6
+ // Grid
7
+ .visualizador-grid,
8
+ .visualizador-grid-css {
9
+ width: 100%;
10
+ height: 100%;
11
+ min-width: 90vh;
12
+ min-height: 80vh;
13
+ background: #ffffff;
14
+ border-radius: 12px;
15
+ display: grid;
16
+ border: solid 2px #900604;
17
+ position: relative;
18
+ gap: 1px;
19
+ box-sizing: content-box;
20
+ }
21
+
22
+ // Slot
23
+ .visualizador-slot {
24
+ display: flex;
25
+ border: 1px solid #900604;
26
+ border-radius: 7px;
27
+ background: #fff;
28
+
29
+ // Direction
30
+ &--row,
31
+ &-row {
32
+ flex-direction: row;
33
+ }
34
+ &--column,
35
+ &-column,
36
+ &-column-col {
37
+ flex-direction: column;
38
+ }
39
+
40
+ // Content size
41
+ &-content--small {
42
+ font-size: 0.85rem;
43
+ }
44
+ &-content--medium {
45
+ font-size: 1rem;
46
+ }
47
+ &-content--large {
48
+ font-size: 1.5rem;
49
+ }
50
+
51
+ // Alignment
52
+ &-align--start {
53
+ align-items: flex-start;
54
+ }
55
+ &-align--center {
56
+ align-items: center;
57
+ }
58
+ &-align--end {
59
+ align-items: flex-end;
60
+ }
61
+ &-align--stretch {
62
+ align-items: stretch;
63
+ }
64
+
65
+ // Justification
66
+ &-justify--start {
67
+ justify-content: flex-start;
68
+ }
69
+ &-justify--center {
70
+ justify-content: center;
71
+ }
72
+ &-justify--end {
73
+ justify-content: flex-end;
74
+ }
75
+ &-justify--space-between {
76
+ justify-content: space-between;
77
+ }
78
+ &-justify--space-around {
79
+ justify-content: space-around;
80
+ }
81
+ &-justify--space-evenly {
82
+ justify-content: space-evenly;
83
+ }
84
+ &--no-border {
85
+ border: none !important;
86
+ }
87
+ }
88
+
89
+ // Legend
90
+ .slot-legend {
91
+ width: auto;
92
+ font-size: 0.75rem;
93
+ margin-bottom: 0px !important;
94
+ margin-left: -20px !important;
95
+ font-weight: 700;
96
+ color: #900604;
97
+ white-space: nowrap;
98
+ }
99
+
100
+ // Editor Layer
101
+ .editor-layer {
102
+ position: absolute;
103
+ width: 100%;
104
+ height: 100%;
105
+ pointer-events: none;
106
+ z-index: 20;
107
+ display: grid;
108
+ }
109
+ .editor-layer-cell-coord {
110
+ font-size: 0.75rem;
111
+ justify-self: center;
112
+ }
113
+ .editor-layer-cell {
114
+ font-size: 0.7em;
115
+ color: #797979;
116
+ align-content: center;
117
+ padding: 2px;
118
+ text-align: left;
119
+ pointer-events: none;
120
+ box-sizing: border-box;
121
+ border: 1px dashed #bbb;
122
+ }
123
+
124
+ // Editor Button
125
+ .visualizador-editor-btn {
126
+ position: absolute;
127
+ top: 8px;
128
+ right: 8px;
129
+ z-index: 100;
130
+ padding: 6px 12px;
131
+ font-size: 1em;
132
+ color: #fff;
133
+ border: none;
134
+ border-radius: 4px;
135
+ cursor: pointer;
136
+
137
+ &--activo {
138
+ background: #900604;
139
+ }
140
+ &--inactivo {
141
+ background: #bbb;
142
+ }
143
+ }
package/tsconfig.json CHANGED
@@ -1,11 +1,7 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "target": "es6",
4
- "lib": [
5
- "dom",
6
- "dom.iterable",
7
- "esnext"
8
- ],
4
+ "lib": ["dom", "dom.iterable", "esnext"],
9
5
  "allowJs": true,
10
6
  "esModuleInterop": true,
11
7
  "skipLibCheck": true,
@@ -17,10 +13,7 @@
17
13
  "resolveJsonModule": true,
18
14
  "isolatedModules": true,
19
15
  "noEmit": true,
20
- "jsx": "preserve",
16
+ "jsx": "preserve"
21
17
  },
22
- "include": [
23
- "src",
24
- "index.d.ts"
25
- ]
26
- }
18
+ "include": ["src", "index.d.ts"]
19
+ }