@bookklik/senangstart-icons 1.0.7 → 1.0.11
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/.agent/skills/build-scripts/SKILL.md +155 -0
- package/.agent/skills/icon-development/SKILL.md +154 -0
- package/.agent/skills/senangstart-icons-architecture/SKILL.md +123 -0
- package/.agent/skills/testing/SKILL.md +202 -0
- package/.agent/skills/web-components/SKILL.md +209 -0
- package/.agent/workflows/add-icon.md +85 -0
- package/.agent/workflows/build.md +73 -0
- package/.agent/workflows/dev.md +52 -0
- package/.agent/workflows/docs.md +77 -0
- package/.agent/workflows/publish.md +80 -0
- package/.agent/workflows/test.md +56 -0
- package/.github/workflows/deploy-docs.yml +61 -0
- package/README.md +5 -5
- package/docs/.vitepress/config.mjs +173 -0
- package/docs/.vitepress/theme/custom.css +64 -0
- package/docs/.vitepress/theme/index.js +4 -0
- package/docs/guide/configuration.md +80 -0
- package/docs/guide/getting-started.md +41 -0
- package/docs/guide/installation.md +54 -0
- package/docs/guide/styling.md +156 -0
- package/docs/guide/usage.md +96 -0
- package/docs/icons/alert.md +55 -0
- package/docs/icons/align-bottom-object.md +55 -0
- package/docs/icons/align-center-object.md +55 -0
- package/docs/icons/align-left-object.md +55 -0
- package/docs/icons/align-middle-object.md +55 -0
- package/docs/icons/align-right-object.md +55 -0
- package/docs/icons/align-top-object.md +55 -0
- package/docs/icons/ar.md +55 -0
- package/docs/icons/archive-box.md +55 -0
- package/docs/icons/arrow-down.md +55 -0
- package/docs/icons/arrow-left-arrow-right.md +55 -0
- package/docs/icons/arrow-left-on-rectangle.md +55 -0
- package/docs/icons/arrow-left-right.md +55 -0
- package/docs/icons/arrow-left.md +55 -0
- package/docs/icons/arrow-long-down.md +55 -0
- package/docs/icons/arrow-long-left.md +55 -0
- package/docs/icons/arrow-long-right.md +55 -0
- package/docs/icons/arrow-long-up.md +55 -0
- package/docs/icons/arrow-path.md +55 -0
- package/docs/icons/arrow-right-on-rectangle.md +55 -0
- package/docs/icons/arrow-right.md +55 -0
- package/docs/icons/arrow-rotate-ccw.md +55 -0
- package/docs/icons/arrow-rotate-cw.md +55 -0
- package/docs/icons/arrow-top-right-on-square.md +55 -0
- package/docs/icons/arrow-up-arrow-down.md +55 -0
- package/docs/icons/arrow-up-down-left-right.md +55 -0
- package/docs/icons/arrow-up-down.md +55 -0
- package/docs/icons/arrow-up.md +55 -0
- package/docs/icons/banknotes.md +55 -0
- package/docs/icons/bars-3.md +55 -0
- package/docs/icons/basket.md +55 -0
- package/docs/icons/battery-0.md +55 -0
- package/docs/icons/battery-10.md +55 -0
- package/docs/icons/battery-100.md +55 -0
- package/docs/icons/battery-50.md +55 -0
- package/docs/icons/bell-alert.md +55 -0
- package/docs/icons/bell.md +55 -0
- package/docs/icons/bolt.md +55 -0
- package/docs/icons/book-close.md +55 -0
- package/docs/icons/book-open.md +55 -0
- package/docs/icons/book-stacked.md +55 -0
- package/docs/icons/bookmark.md +55 -0
- package/docs/icons/briefcase.md +55 -0
- package/docs/icons/brush.md +55 -0
- package/docs/icons/cake.md +55 -0
- package/docs/icons/calendar-approve.md +55 -0
- package/docs/icons/calendar-days.md +55 -0
- package/docs/icons/calendar-minus.md +55 -0
- package/docs/icons/calendar-plus.md +55 -0
- package/docs/icons/calendar-reject.md +55 -0
- package/docs/icons/calendar.md +55 -0
- package/docs/icons/camera.md +55 -0
- package/docs/icons/carousel.md +55 -0
- package/docs/icons/chart-bar.md +55 -0
- package/docs/icons/chart-line.md +55 -0
- package/docs/icons/chart-pie.md +55 -0
- package/docs/icons/chat-bubble-left-ellipsis.md +55 -0
- package/docs/icons/chat-bubble-left-right.md +55 -0
- package/docs/icons/chat-bubble-left.md +55 -0
- package/docs/icons/chat-bubble-right-ellipsis.md +55 -0
- package/docs/icons/chat-bubble-right.md +55 -0
- package/docs/icons/chatbot.md +55 -0
- package/docs/icons/check.md +55 -0
- package/docs/icons/chevron-double-down.md +55 -0
- package/docs/icons/chevron-double-left.md +55 -0
- package/docs/icons/chevron-double-right.md +55 -0
- package/docs/icons/chevron-double-up.md +55 -0
- package/docs/icons/chevron-down.md +55 -0
- package/docs/icons/chevron-left.md +55 -0
- package/docs/icons/chevron-right.md +55 -0
- package/docs/icons/chevron-up.md +55 -0
- package/docs/icons/circle.md +55 -0
- package/docs/icons/clipboard-document-check.md +55 -0
- package/docs/icons/clipboard.md +55 -0
- package/docs/icons/clock.md +55 -0
- package/docs/icons/cloud.md +55 -0
- package/docs/icons/code.md +55 -0
- package/docs/icons/cog-6-tooth.md +55 -0
- package/docs/icons/compress.md +55 -0
- package/docs/icons/computer-code.md +55 -0
- package/docs/icons/computer-desktop.md +55 -0
- package/docs/icons/computer-laptop.md +55 -0
- package/docs/icons/cone.md +55 -0
- package/docs/icons/console.md +55 -0
- package/docs/icons/container.md +55 -0
- package/docs/icons/contrast.md +55 -0
- package/docs/icons/controller.md +55 -0
- package/docs/icons/credit-card.md +55 -0
- package/docs/icons/crop.md +55 -0
- package/docs/icons/crosshair.md +55 -0
- package/docs/icons/cube.md +55 -0
- package/docs/icons/currency-dollar.md +55 -0
- package/docs/icons/currency-euro.md +55 -0
- package/docs/icons/currency-pound.md +55 -0
- package/docs/icons/currency-ringgit.md +55 -0
- package/docs/icons/currency-yen.md +55 -0
- package/docs/icons/cursor.md +55 -0
- package/docs/icons/cylinder-half.md +55 -0
- package/docs/icons/cylinder.md +55 -0
- package/docs/icons/device-phone-mobile.md +55 -0
- package/docs/icons/device-tablet.md +55 -0
- package/docs/icons/diamond.md +55 -0
- package/docs/icons/document-duplicate.md +55 -0
- package/docs/icons/document-text.md +55 -0
- package/docs/icons/document.md +55 -0
- package/docs/icons/dodecahedron.md +55 -0
- package/docs/icons/double-tick.md +55 -0
- package/docs/icons/draw-curve.md +55 -0
- package/docs/icons/draw-line.md +55 -0
- package/docs/icons/envelope-open.md +55 -0
- package/docs/icons/envelope.md +55 -0
- package/docs/icons/eraser.md +55 -0
- package/docs/icons/exclamation-circle.md +55 -0
- package/docs/icons/exclamation-triangle.md +55 -0
- package/docs/icons/expand.md +55 -0
- package/docs/icons/eye-slash.md +55 -0
- package/docs/icons/eye.md +55 -0
- package/docs/icons/flag.md +55 -0
- package/docs/icons/flip-horizontal.md +55 -0
- package/docs/icons/flip-vertical.md +55 -0
- package/docs/icons/focus.md +55 -0
- package/docs/icons/folder-minus.md +55 -0
- package/docs/icons/folder-open.md +55 -0
- package/docs/icons/folder-plus.md +55 -0
- package/docs/icons/folder.md +55 -0
- package/docs/icons/font.md +55 -0
- package/docs/icons/game.md +55 -0
- package/docs/icons/gift.md +55 -0
- package/docs/icons/globe-alt.md +55 -0
- package/docs/icons/gradient.md +55 -0
- package/docs/icons/grid.md +55 -0
- package/docs/icons/group-object.md +55 -0
- package/docs/icons/hand-grab.md +55 -0
- package/docs/icons/hand-thumb-down.md +55 -0
- package/docs/icons/hand-thumb-up.md +55 -0
- package/docs/icons/hand.md +55 -0
- package/docs/icons/heart-extruded.md +55 -0
- package/docs/icons/heart.md +55 -0
- package/docs/icons/hexagon.md +55 -0
- package/docs/icons/home.md +55 -0
- package/docs/icons/horizontal-3-dots.md +55 -0
- package/docs/icons/hourglass-0.md +55 -0
- package/docs/icons/hourglass-100.md +55 -0
- package/docs/icons/hourglass-50.md +55 -0
- package/docs/icons/hourglass-80.md +55 -0
- package/docs/icons/icosahedron.md +55 -0
- package/docs/icons/inbox.md +55 -0
- package/docs/icons/index.md +1295 -0
- package/docs/icons/information-circle.md +55 -0
- package/docs/icons/key.md +55 -0
- package/docs/icons/layer-stacks.md +55 -0
- package/docs/icons/layout.md +55 -0
- package/docs/icons/light-bulb.md +55 -0
- package/docs/icons/lock-closed.md +55 -0
- package/docs/icons/lock-open.md +55 -0
- package/docs/icons/magic-wand.md +55 -0
- package/docs/icons/magnifying-glass-focus.md +55 -0
- package/docs/icons/magnifying-glass-minus.md +55 -0
- package/docs/icons/magnifying-glass-plus.md +55 -0
- package/docs/icons/magnifying-glass.md +55 -0
- package/docs/icons/map-pin.md +55 -0
- package/docs/icons/map.md +55 -0
- package/docs/icons/marquee.md +55 -0
- package/docs/icons/maximize.md +55 -0
- package/docs/icons/medal.md +55 -0
- package/docs/icons/microphone-mute.md +55 -0
- package/docs/icons/microphone.md +55 -0
- package/docs/icons/minimize.md +55 -0
- package/docs/icons/minus.md +55 -0
- package/docs/icons/moon.md +55 -0
- package/docs/icons/musical-note.md +55 -0
- package/docs/icons/octahedron.md +55 -0
- package/docs/icons/panorama.md +55 -0
- package/docs/icons/paper-clip.md +55 -0
- package/docs/icons/pause-circle.md +55 -0
- package/docs/icons/pause.md +55 -0
- package/docs/icons/pencil.md +55 -0
- package/docs/icons/phone-x-mark.md +55 -0
- package/docs/icons/phone.md +55 -0
- package/docs/icons/photo.md +55 -0
- package/docs/icons/plane.md +55 -0
- package/docs/icons/play-circle.md +55 -0
- package/docs/icons/play.md +55 -0
- package/docs/icons/plus.md +55 -0
- package/docs/icons/polygon.md +55 -0
- package/docs/icons/presentation-chart-line.md +55 -0
- package/docs/icons/presentation-media.md +55 -0
- package/docs/icons/pyramid.md +55 -0
- package/docs/icons/qr-code.md +55 -0
- package/docs/icons/question-mark-circle.md +55 -0
- package/docs/icons/rectangle.md +55 -0
- package/docs/icons/reel.md +55 -0
- package/docs/icons/robot.md +55 -0
- package/docs/icons/roof.md +55 -0
- package/docs/icons/rotate-add.md +55 -0
- package/docs/icons/rotate-minus.md +55 -0
- package/docs/icons/save.md +55 -0
- package/docs/icons/scissor.md +55 -0
- package/docs/icons/shapes.md +55 -0
- package/docs/icons/shield-check.md +55 -0
- package/docs/icons/shield-exclamation.md +55 -0
- package/docs/icons/shopping-bag.md +55 -0
- package/docs/icons/shopping-cart.md +55 -0
- package/docs/icons/sliders-horizontal.md +55 -0
- package/docs/icons/sliders-vertical.md +55 -0
- package/docs/icons/sparkles.md +55 -0
- package/docs/icons/speaker-wave.md +55 -0
- package/docs/icons/speaker-x-mark.md +55 -0
- package/docs/icons/sphere-half.md +55 -0
- package/docs/icons/sphere.md +55 -0
- package/docs/icons/square.md +55 -0
- package/docs/icons/star.md +55 -0
- package/docs/icons/stop-circle.md +55 -0
- package/docs/icons/stop.md +55 -0
- package/docs/icons/sun.md +55 -0
- package/docs/icons/table.md +55 -0
- package/docs/icons/tabs.md +55 -0
- package/docs/icons/tetrahedron.md +55 -0
- package/docs/icons/text-align-center.md +55 -0
- package/docs/icons/text-align-justify.md +55 -0
- package/docs/icons/text-align-left.md +55 -0
- package/docs/icons/text-align-right.md +55 -0
- package/docs/icons/text.md +55 -0
- package/docs/icons/thunder.md +55 -0
- package/docs/icons/tic-tac-toe.md +55 -0
- package/docs/icons/time-reset.md +55 -0
- package/docs/icons/torus-knot.md +55 -0
- package/docs/icons/torus.md +55 -0
- package/docs/icons/trash.md +55 -0
- package/docs/icons/trophy.md +55 -0
- package/docs/icons/truck.md +55 -0
- package/docs/icons/tube.md +55 -0
- package/docs/icons/ungroup-object.md +55 -0
- package/docs/icons/user-circle.md +55 -0
- package/docs/icons/user-group.md +55 -0
- package/docs/icons/user-minus.md +55 -0
- package/docs/icons/user-plus.md +55 -0
- package/docs/icons/user.md +55 -0
- package/docs/icons/users.md +55 -0
- package/docs/icons/vertical-3-dots.md +55 -0
- package/docs/icons/video-camera.md +55 -0
- package/docs/icons/vr.md +55 -0
- package/docs/icons/wedge.md +55 -0
- package/docs/icons/whiteboard.md +55 -0
- package/docs/icons/wifi.md +55 -0
- package/docs/icons/window.md +55 -0
- package/docs/icons/x-mark.md +55 -0
- package/docs/index.md +55 -0
- package/docs/ms/guide/configuration.md +80 -0
- package/docs/ms/guide/getting-started.md +41 -0
- package/docs/ms/guide/installation.md +54 -0
- package/docs/ms/guide/styling.md +156 -0
- package/docs/ms/guide/usage.md +96 -0
- package/docs/ms/icons/alert.md +55 -0
- package/docs/ms/icons/align-bottom-object.md +55 -0
- package/docs/ms/icons/align-center-object.md +55 -0
- package/docs/ms/icons/align-left-object.md +55 -0
- package/docs/ms/icons/align-middle-object.md +55 -0
- package/docs/ms/icons/align-right-object.md +55 -0
- package/docs/ms/icons/align-top-object.md +55 -0
- package/docs/ms/icons/ar.md +55 -0
- package/docs/ms/icons/archive-box.md +55 -0
- package/docs/ms/icons/arrow-down.md +55 -0
- package/docs/ms/icons/arrow-left-arrow-right.md +55 -0
- package/docs/ms/icons/arrow-left-on-rectangle.md +55 -0
- package/docs/ms/icons/arrow-left-right.md +55 -0
- package/docs/ms/icons/arrow-left.md +55 -0
- package/docs/ms/icons/arrow-long-down.md +55 -0
- package/docs/ms/icons/arrow-long-left.md +55 -0
- package/docs/ms/icons/arrow-long-right.md +55 -0
- package/docs/ms/icons/arrow-long-up.md +55 -0
- package/docs/ms/icons/arrow-path.md +55 -0
- package/docs/ms/icons/arrow-right-on-rectangle.md +55 -0
- package/docs/ms/icons/arrow-right.md +55 -0
- package/docs/ms/icons/arrow-rotate-ccw.md +55 -0
- package/docs/ms/icons/arrow-rotate-cw.md +55 -0
- package/docs/ms/icons/arrow-top-right-on-square.md +55 -0
- package/docs/ms/icons/arrow-up-arrow-down.md +55 -0
- package/docs/ms/icons/arrow-up-down-left-right.md +55 -0
- package/docs/ms/icons/arrow-up-down.md +55 -0
- package/docs/ms/icons/arrow-up.md +55 -0
- package/docs/ms/icons/banknotes.md +55 -0
- package/docs/ms/icons/bars-3.md +55 -0
- package/docs/ms/icons/basket.md +55 -0
- package/docs/ms/icons/battery-0.md +55 -0
- package/docs/ms/icons/battery-10.md +55 -0
- package/docs/ms/icons/battery-100.md +55 -0
- package/docs/ms/icons/battery-50.md +55 -0
- package/docs/ms/icons/bell-alert.md +55 -0
- package/docs/ms/icons/bell.md +55 -0
- package/docs/ms/icons/bolt.md +55 -0
- package/docs/ms/icons/book-close.md +55 -0
- package/docs/ms/icons/book-open.md +55 -0
- package/docs/ms/icons/book-stacked.md +55 -0
- package/docs/ms/icons/bookmark.md +55 -0
- package/docs/ms/icons/briefcase.md +55 -0
- package/docs/ms/icons/brush.md +55 -0
- package/docs/ms/icons/cake.md +55 -0
- package/docs/ms/icons/calendar-approve.md +55 -0
- package/docs/ms/icons/calendar-days.md +55 -0
- package/docs/ms/icons/calendar-minus.md +55 -0
- package/docs/ms/icons/calendar-plus.md +55 -0
- package/docs/ms/icons/calendar-reject.md +55 -0
- package/docs/ms/icons/calendar.md +55 -0
- package/docs/ms/icons/camera.md +55 -0
- package/docs/ms/icons/carousel.md +55 -0
- package/docs/ms/icons/chart-bar.md +55 -0
- package/docs/ms/icons/chart-line.md +55 -0
- package/docs/ms/icons/chart-pie.md +55 -0
- package/docs/ms/icons/chat-bubble-left-ellipsis.md +55 -0
- package/docs/ms/icons/chat-bubble-left-right.md +55 -0
- package/docs/ms/icons/chat-bubble-left.md +55 -0
- package/docs/ms/icons/chat-bubble-right-ellipsis.md +55 -0
- package/docs/ms/icons/chat-bubble-right.md +55 -0
- package/docs/ms/icons/chatbot.md +55 -0
- package/docs/ms/icons/check.md +55 -0
- package/docs/ms/icons/chevron-double-down.md +55 -0
- package/docs/ms/icons/chevron-double-left.md +55 -0
- package/docs/ms/icons/chevron-double-right.md +55 -0
- package/docs/ms/icons/chevron-double-up.md +55 -0
- package/docs/ms/icons/chevron-down.md +55 -0
- package/docs/ms/icons/chevron-left.md +55 -0
- package/docs/ms/icons/chevron-right.md +55 -0
- package/docs/ms/icons/chevron-up.md +55 -0
- package/docs/ms/icons/circle.md +55 -0
- package/docs/ms/icons/clipboard-document-check.md +55 -0
- package/docs/ms/icons/clipboard.md +55 -0
- package/docs/ms/icons/clock.md +55 -0
- package/docs/ms/icons/cloud.md +55 -0
- package/docs/ms/icons/code.md +55 -0
- package/docs/ms/icons/cog-6-tooth.md +55 -0
- package/docs/ms/icons/compress.md +55 -0
- package/docs/ms/icons/computer-code.md +55 -0
- package/docs/ms/icons/computer-desktop.md +55 -0
- package/docs/ms/icons/computer-laptop.md +55 -0
- package/docs/ms/icons/cone.md +55 -0
- package/docs/ms/icons/console.md +55 -0
- package/docs/ms/icons/container.md +55 -0
- package/docs/ms/icons/contrast.md +55 -0
- package/docs/ms/icons/controller.md +55 -0
- package/docs/ms/icons/credit-card.md +55 -0
- package/docs/ms/icons/crop.md +55 -0
- package/docs/ms/icons/crosshair.md +55 -0
- package/docs/ms/icons/cube.md +55 -0
- package/docs/ms/icons/currency-dollar.md +55 -0
- package/docs/ms/icons/currency-euro.md +55 -0
- package/docs/ms/icons/currency-pound.md +55 -0
- package/docs/ms/icons/currency-ringgit.md +55 -0
- package/docs/ms/icons/currency-yen.md +55 -0
- package/docs/ms/icons/cursor.md +55 -0
- package/docs/ms/icons/cylinder-half.md +55 -0
- package/docs/ms/icons/cylinder.md +55 -0
- package/docs/ms/icons/device-phone-mobile.md +55 -0
- package/docs/ms/icons/device-tablet.md +55 -0
- package/docs/ms/icons/diamond.md +55 -0
- package/docs/ms/icons/document-duplicate.md +55 -0
- package/docs/ms/icons/document-text.md +55 -0
- package/docs/ms/icons/document.md +55 -0
- package/docs/ms/icons/dodecahedron.md +55 -0
- package/docs/ms/icons/double-tick.md +55 -0
- package/docs/ms/icons/draw-curve.md +55 -0
- package/docs/ms/icons/draw-line.md +55 -0
- package/docs/ms/icons/envelope-open.md +55 -0
- package/docs/ms/icons/envelope.md +55 -0
- package/docs/ms/icons/eraser.md +55 -0
- package/docs/ms/icons/exclamation-circle.md +55 -0
- package/docs/ms/icons/exclamation-triangle.md +55 -0
- package/docs/ms/icons/expand.md +55 -0
- package/docs/ms/icons/eye-slash.md +55 -0
- package/docs/ms/icons/eye.md +55 -0
- package/docs/ms/icons/flag.md +55 -0
- package/docs/ms/icons/flip-horizontal.md +55 -0
- package/docs/ms/icons/flip-vertical.md +55 -0
- package/docs/ms/icons/focus.md +55 -0
- package/docs/ms/icons/folder-minus.md +55 -0
- package/docs/ms/icons/folder-open.md +55 -0
- package/docs/ms/icons/folder-plus.md +55 -0
- package/docs/ms/icons/folder.md +55 -0
- package/docs/ms/icons/font.md +55 -0
- package/docs/ms/icons/game.md +55 -0
- package/docs/ms/icons/gift.md +55 -0
- package/docs/ms/icons/globe-alt.md +55 -0
- package/docs/ms/icons/gradient.md +55 -0
- package/docs/ms/icons/grid.md +55 -0
- package/docs/ms/icons/group-object.md +55 -0
- package/docs/ms/icons/hand-grab.md +55 -0
- package/docs/ms/icons/hand-thumb-down.md +55 -0
- package/docs/ms/icons/hand-thumb-up.md +55 -0
- package/docs/ms/icons/hand.md +55 -0
- package/docs/ms/icons/heart-extruded.md +55 -0
- package/docs/ms/icons/heart.md +55 -0
- package/docs/ms/icons/hexagon.md +55 -0
- package/docs/ms/icons/home.md +55 -0
- package/docs/ms/icons/horizontal-3-dots.md +55 -0
- package/docs/ms/icons/hourglass-0.md +55 -0
- package/docs/ms/icons/hourglass-100.md +55 -0
- package/docs/ms/icons/hourglass-50.md +55 -0
- package/docs/ms/icons/hourglass-80.md +55 -0
- package/docs/ms/icons/icosahedron.md +55 -0
- package/docs/ms/icons/inbox.md +55 -0
- package/docs/ms/icons/index.md +1295 -0
- package/docs/ms/icons/information-circle.md +55 -0
- package/docs/ms/icons/key.md +55 -0
- package/docs/ms/icons/layer-stacks.md +55 -0
- package/docs/ms/icons/layout.md +55 -0
- package/docs/ms/icons/light-bulb.md +55 -0
- package/docs/ms/icons/lock-closed.md +55 -0
- package/docs/ms/icons/lock-open.md +55 -0
- package/docs/ms/icons/magic-wand.md +55 -0
- package/docs/ms/icons/magnifying-glass-focus.md +55 -0
- package/docs/ms/icons/magnifying-glass-minus.md +55 -0
- package/docs/ms/icons/magnifying-glass-plus.md +55 -0
- package/docs/ms/icons/magnifying-glass.md +55 -0
- package/docs/ms/icons/map-pin.md +55 -0
- package/docs/ms/icons/map.md +55 -0
- package/docs/ms/icons/marquee.md +55 -0
- package/docs/ms/icons/maximize.md +55 -0
- package/docs/ms/icons/medal.md +55 -0
- package/docs/ms/icons/microphone-mute.md +55 -0
- package/docs/ms/icons/microphone.md +55 -0
- package/docs/ms/icons/minimize.md +55 -0
- package/docs/ms/icons/minus.md +55 -0
- package/docs/ms/icons/moon.md +55 -0
- package/docs/ms/icons/musical-note.md +55 -0
- package/docs/ms/icons/octahedron.md +55 -0
- package/docs/ms/icons/panorama.md +55 -0
- package/docs/ms/icons/paper-clip.md +55 -0
- package/docs/ms/icons/pause-circle.md +55 -0
- package/docs/ms/icons/pause.md +55 -0
- package/docs/ms/icons/pencil.md +55 -0
- package/docs/ms/icons/phone-x-mark.md +55 -0
- package/docs/ms/icons/phone.md +55 -0
- package/docs/ms/icons/photo.md +55 -0
- package/docs/ms/icons/plane.md +55 -0
- package/docs/ms/icons/play-circle.md +55 -0
- package/docs/ms/icons/play.md +55 -0
- package/docs/ms/icons/plus.md +55 -0
- package/docs/ms/icons/polygon.md +55 -0
- package/docs/ms/icons/presentation-chart-line.md +55 -0
- package/docs/ms/icons/presentation-media.md +55 -0
- package/docs/ms/icons/pyramid.md +55 -0
- package/docs/ms/icons/qr-code.md +55 -0
- package/docs/ms/icons/question-mark-circle.md +55 -0
- package/docs/ms/icons/rectangle.md +55 -0
- package/docs/ms/icons/reel.md +55 -0
- package/docs/ms/icons/robot.md +55 -0
- package/docs/ms/icons/roof.md +55 -0
- package/docs/ms/icons/rotate-add.md +55 -0
- package/docs/ms/icons/rotate-minus.md +55 -0
- package/docs/ms/icons/save.md +55 -0
- package/docs/ms/icons/scissor.md +55 -0
- package/docs/ms/icons/shapes.md +55 -0
- package/docs/ms/icons/shield-check.md +55 -0
- package/docs/ms/icons/shield-exclamation.md +55 -0
- package/docs/ms/icons/shopping-bag.md +55 -0
- package/docs/ms/icons/shopping-cart.md +55 -0
- package/docs/ms/icons/sliders-horizontal.md +55 -0
- package/docs/ms/icons/sliders-vertical.md +55 -0
- package/docs/ms/icons/sparkles.md +55 -0
- package/docs/ms/icons/speaker-wave.md +55 -0
- package/docs/ms/icons/speaker-x-mark.md +55 -0
- package/docs/ms/icons/sphere-half.md +55 -0
- package/docs/ms/icons/sphere.md +55 -0
- package/docs/ms/icons/square.md +55 -0
- package/docs/ms/icons/star.md +55 -0
- package/docs/ms/icons/stop-circle.md +55 -0
- package/docs/ms/icons/stop.md +55 -0
- package/docs/ms/icons/sun.md +55 -0
- package/docs/ms/icons/table.md +55 -0
- package/docs/ms/icons/tabs.md +55 -0
- package/docs/ms/icons/tetrahedron.md +55 -0
- package/docs/ms/icons/text-align-center.md +55 -0
- package/docs/ms/icons/text-align-justify.md +55 -0
- package/docs/ms/icons/text-align-left.md +55 -0
- package/docs/ms/icons/text-align-right.md +55 -0
- package/docs/ms/icons/text.md +55 -0
- package/docs/ms/icons/thunder.md +55 -0
- package/docs/ms/icons/tic-tac-toe.md +55 -0
- package/docs/ms/icons/time-reset.md +55 -0
- package/docs/ms/icons/torus-knot.md +55 -0
- package/docs/ms/icons/torus.md +55 -0
- package/docs/ms/icons/trash.md +55 -0
- package/docs/ms/icons/trophy.md +55 -0
- package/docs/ms/icons/truck.md +55 -0
- package/docs/ms/icons/tube.md +55 -0
- package/docs/ms/icons/ungroup-object.md +55 -0
- package/docs/ms/icons/user-circle.md +55 -0
- package/docs/ms/icons/user-group.md +55 -0
- package/docs/ms/icons/user-minus.md +55 -0
- package/docs/ms/icons/user-plus.md +55 -0
- package/docs/ms/icons/user.md +55 -0
- package/docs/ms/icons/users.md +55 -0
- package/docs/ms/icons/vertical-3-dots.md +55 -0
- package/docs/ms/icons/video-camera.md +55 -0
- package/docs/ms/icons/vr.md +55 -0
- package/docs/ms/icons/wedge.md +55 -0
- package/docs/ms/icons/whiteboard.md +55 -0
- package/docs/ms/icons/wifi.md +55 -0
- package/docs/ms/icons/window.md +55 -0
- package/docs/ms/icons/x-mark.md +55 -0
- package/docs/ms/index.md +55 -0
- package/docs/public/assets/senangstart-icons-logo.svg +1 -0
- package/docs/public/assets/ss-logo.svg +83 -0
- package/docs/public/llms.txt +285 -0
- package/package.json +13 -3
- package/scripts/build-icon-docs.js +323 -0
- package/scripts/build.js +44 -0
- package/scripts/generate-llms-txt.js +70 -0
- package/test-results.json +11 -0
- package/tests/build-css.test.js +134 -0
- package/tests/build-icon-docs.test.js +134 -0
- package/tests/build-pipeline.test.js +138 -0
- package/tests/build-svgs.test.js +102 -0
- package/tests/ss-icon.test.js +178 -0
- package/tests/ss-loader.test.js +156 -0
- package/vitest.config.js +15 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for build-icon-docs.js
|
|
3
|
+
*
|
|
4
|
+
* Tests documentation generation for icons
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, beforeAll } from 'vitest';
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
|
|
10
|
+
const iconsPath = path.resolve(__dirname, '../src/icons.json');
|
|
11
|
+
const docsIconsDir = path.resolve(__dirname, '../docs/icons');
|
|
12
|
+
const docsIconsDirMs = path.resolve(__dirname, '../docs/ms/icons');
|
|
13
|
+
|
|
14
|
+
describe('build-icon-docs.js', () => {
|
|
15
|
+
let icons;
|
|
16
|
+
|
|
17
|
+
beforeAll(() => {
|
|
18
|
+
icons = JSON.parse(fs.readFileSync(iconsPath, 'utf8'));
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe('English documentation', () => {
|
|
22
|
+
it('should have docs/icons directory', () => {
|
|
23
|
+
expect(fs.existsSync(docsIconsDir)).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should generate index.md', () => {
|
|
27
|
+
const indexPath = path.join(docsIconsDir, 'index.md');
|
|
28
|
+
expect(fs.existsSync(indexPath)).toBe(true);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should generate a markdown file for each icon', () => {
|
|
32
|
+
icons.forEach(icon => {
|
|
33
|
+
const mdPath = path.join(docsIconsDir, `${icon.slug}.md`);
|
|
34
|
+
expect(fs.existsSync(mdPath)).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should have proper frontmatter in icon pages', () => {
|
|
39
|
+
const sampleIcon = icons[0];
|
|
40
|
+
const mdPath = path.join(docsIconsDir, `${sampleIcon.slug}.md`);
|
|
41
|
+
const content = fs.readFileSync(mdPath, 'utf8');
|
|
42
|
+
|
|
43
|
+
expect(content).toContain('---');
|
|
44
|
+
expect(content).toContain(`title: ${sampleIcon.name}`);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should include usage examples', () => {
|
|
48
|
+
const sampleIcon = icons[0];
|
|
49
|
+
const mdPath = path.join(docsIconsDir, `${sampleIcon.slug}.md`);
|
|
50
|
+
const content = fs.readFileSync(mdPath, 'utf8');
|
|
51
|
+
|
|
52
|
+
expect(content).toContain('## Usage');
|
|
53
|
+
expect(content).toContain(`<ss-icon icon="${sampleIcon.slug}">`);
|
|
54
|
+
expect(content).toContain(`<i class="ss ss-${sampleIcon.slug}"></i>`);
|
|
55
|
+
expect(content).toContain(`thickness="1.2"`);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should include icon details table', () => {
|
|
59
|
+
const sampleIcon = icons[0];
|
|
60
|
+
const mdPath = path.join(docsIconsDir, `${sampleIcon.slug}.md`);
|
|
61
|
+
const content = fs.readFileSync(mdPath, 'utf8');
|
|
62
|
+
|
|
63
|
+
expect(content).toContain('## Icon Details');
|
|
64
|
+
expect(content).toContain('| Property | Value |');
|
|
65
|
+
expect(content).toContain(`| **Name** | ${sampleIcon.name} |`);
|
|
66
|
+
expect(content).toContain(`| **Slug** | \`${sampleIcon.slug}\` |`);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('should include SVG path data', () => {
|
|
70
|
+
const sampleIcon = icons[0];
|
|
71
|
+
const mdPath = path.join(docsIconsDir, `${sampleIcon.slug}.md`);
|
|
72
|
+
const content = fs.readFileSync(mdPath, 'utf8');
|
|
73
|
+
|
|
74
|
+
expect(content).toContain('## SVG Path');
|
|
75
|
+
expect(content).toContain(sampleIcon.src);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should have index with all icons', () => {
|
|
79
|
+
const indexPath = path.join(docsIconsDir, 'index.md');
|
|
80
|
+
const content = fs.readFileSync(indexPath, 'utf8');
|
|
81
|
+
|
|
82
|
+
expect(content).toContain(`${icons.length}`);
|
|
83
|
+
expect(content).toContain('icon-grid');
|
|
84
|
+
|
|
85
|
+
// Check that at least some icons are linked
|
|
86
|
+
const sampleIcon = icons[0];
|
|
87
|
+
expect(content).toContain(`href="./${sampleIcon.slug}"`);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
describe('Malay documentation', () => {
|
|
92
|
+
it('should have docs/ms/icons directory', () => {
|
|
93
|
+
expect(fs.existsSync(docsIconsDirMs)).toBe(true);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('should generate index.md in Malay', () => {
|
|
97
|
+
const indexPath = path.join(docsIconsDirMs, 'index.md');
|
|
98
|
+
expect(fs.existsSync(indexPath)).toBe(true);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('should generate a markdown file for each icon', () => {
|
|
102
|
+
icons.forEach(icon => {
|
|
103
|
+
const mdPath = path.join(docsIconsDirMs, `${icon.slug}.md`);
|
|
104
|
+
expect(fs.existsSync(mdPath)).toBe(true);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('should have Malay-translated content', () => {
|
|
109
|
+
const sampleIcon = icons[0];
|
|
110
|
+
const mdPath = path.join(docsIconsDirMs, `${sampleIcon.slug}.md`);
|
|
111
|
+
const content = fs.readFileSync(mdPath, 'utf8');
|
|
112
|
+
|
|
113
|
+
expect(content).toContain('## Penggunaan'); // "Usage" in Malay
|
|
114
|
+
expect(content).toContain('## Butiran Ikon'); // "Icon Details" in Malay
|
|
115
|
+
expect(content).toContain('## Laluan SVG'); // "SVG Path" in Malay
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('should link back to Malay icon library', () => {
|
|
119
|
+
const sampleIcon = icons[0];
|
|
120
|
+
const mdPath = path.join(docsIconsDirMs, `${sampleIcon.slug}.md`);
|
|
121
|
+
const content = fs.readFileSync(mdPath, 'utf8');
|
|
122
|
+
|
|
123
|
+
expect(content).toContain('[← Kembali ke Pustaka Ikon](/ms/icons/)');
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should have Malay index with all icons', () => {
|
|
127
|
+
const indexPath = path.join(docsIconsDirMs, 'index.md');
|
|
128
|
+
const content = fs.readFileSync(indexPath, 'utf8');
|
|
129
|
+
|
|
130
|
+
expect(content).toContain('Pustaka Ikon'); // "Icon Library" in Malay
|
|
131
|
+
expect(content).toContain(`href="./${icons[0].slug}"`);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
});
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration tests for the build pipeline
|
|
3
|
+
*
|
|
4
|
+
* Tests the complete build output and cross-component consistency
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, beforeAll } from 'vitest';
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
|
|
10
|
+
const projectRoot = path.resolve(__dirname, '..');
|
|
11
|
+
const srcDir = path.join(projectRoot, 'src');
|
|
12
|
+
const svgDir = path.join(srcDir, 'svg');
|
|
13
|
+
const distDir = path.join(projectRoot, 'dist');
|
|
14
|
+
const docsDir = path.join(projectRoot, 'docs');
|
|
15
|
+
|
|
16
|
+
describe('Build Pipeline Integration', () => {
|
|
17
|
+
let icons;
|
|
18
|
+
|
|
19
|
+
beforeAll(() => {
|
|
20
|
+
const iconsPath = path.join(srcDir, 'icons.json');
|
|
21
|
+
icons = JSON.parse(fs.readFileSync(iconsPath, 'utf8'));
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe('Source files', () => {
|
|
25
|
+
it('should have icons.json', () => {
|
|
26
|
+
expect(fs.existsSync(path.join(srcDir, 'icons.json'))).toBe(true);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should have all required source files', () => {
|
|
30
|
+
expect(fs.existsSync(path.join(srcDir, 'index.js'))).toBe(true);
|
|
31
|
+
expect(fs.existsSync(path.join(srcDir, 'ss-icon.js'))).toBe(true);
|
|
32
|
+
expect(fs.existsSync(path.join(srcDir, 'ss-loader.js'))).toBe(true);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe('Generated SVG files', () => {
|
|
37
|
+
it('should have svg directory', () => {
|
|
38
|
+
expect(fs.existsSync(svgDir)).toBe(true);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should have SVG file for each icon in icons.json', () => {
|
|
42
|
+
icons.forEach(icon => {
|
|
43
|
+
const svgPath = path.join(svgDir, `${icon.slug}.svg`);
|
|
44
|
+
expect(fs.existsSync(svgPath)).toBe(true);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should have index.js exporting all icons', () => {
|
|
49
|
+
const indexPath = path.join(svgDir, 'index.js');
|
|
50
|
+
expect(fs.existsSync(indexPath)).toBe(true);
|
|
51
|
+
|
|
52
|
+
const content = fs.readFileSync(indexPath, 'utf8');
|
|
53
|
+
expect(content).toContain('export default icons');
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe('Generated CSS', () => {
|
|
58
|
+
it('should have icons.css file', () => {
|
|
59
|
+
expect(fs.existsSync(path.join(srcDir, 'icons.css'))).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should have CSS class for each icon', () => {
|
|
63
|
+
const cssContent = fs.readFileSync(path.join(srcDir, 'icons.css'), 'utf8');
|
|
64
|
+
|
|
65
|
+
icons.forEach(icon => {
|
|
66
|
+
expect(cssContent).toContain(`.ss-${icon.slug}`);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
describe('Documentation files', () => {
|
|
72
|
+
it('should have docs directory structure', () => {
|
|
73
|
+
expect(fs.existsSync(path.join(docsDir, 'icons'))).toBe(true);
|
|
74
|
+
expect(fs.existsSync(path.join(docsDir, 'ms', 'icons'))).toBe(true);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('should have documentation for each icon', () => {
|
|
78
|
+
icons.forEach(icon => {
|
|
79
|
+
const enPath = path.join(docsDir, 'icons', `${icon.slug}.md`);
|
|
80
|
+
const msPath = path.join(docsDir, 'ms', 'icons', `${icon.slug}.md`);
|
|
81
|
+
|
|
82
|
+
expect(fs.existsSync(enPath)).toBe(true);
|
|
83
|
+
expect(fs.existsSync(msPath)).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
describe('Icon data consistency', () => {
|
|
89
|
+
it('should have matching icon counts across all generated files', () => {
|
|
90
|
+
const svgFiles = fs.readdirSync(svgDir).filter(f => f.endsWith('.svg'));
|
|
91
|
+
const docFiles = fs.readdirSync(path.join(docsDir, 'icons')).filter(f => f.endsWith('.md') && f !== 'index.md');
|
|
92
|
+
|
|
93
|
+
// All icons in icons.json should have corresponding SVG and doc files
|
|
94
|
+
// Note: There may be more files than icons if old files weren't cleaned up
|
|
95
|
+
expect(svgFiles.length).toBeGreaterThanOrEqual(icons.length);
|
|
96
|
+
expect(docFiles.length).toBeGreaterThanOrEqual(icons.length);
|
|
97
|
+
|
|
98
|
+
// Verify each icon has its files
|
|
99
|
+
icons.forEach(icon => {
|
|
100
|
+
expect(svgFiles).toContain(`${icon.slug}.svg`);
|
|
101
|
+
expect(docFiles).toContain(`${icon.slug}.md`);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('should have valid SVG path data in icons.json', () => {
|
|
106
|
+
icons.forEach(icon => {
|
|
107
|
+
// Check that path commands are valid SVG path syntax
|
|
108
|
+
expect(icon.src.length).toBeGreaterThan(0);
|
|
109
|
+
// Should not contain HTML tags or scripts
|
|
110
|
+
expect(icon.src).not.toContain('<script');
|
|
111
|
+
expect(icon.src).not.toContain('javascript:');
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('should have normalized slugs (lowercase, hyphenated)', () => {
|
|
116
|
+
icons.forEach(icon => {
|
|
117
|
+
expect(icon.slug).toMatch(/^[a-z0-9-]+$/);
|
|
118
|
+
expect(icon.slug).not.toContain(' ');
|
|
119
|
+
expect(icon.slug).not.toMatch(/[A-Z]/);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
describe('Build scripts', () => {
|
|
125
|
+
it('should have all build scripts', () => {
|
|
126
|
+
expect(fs.existsSync(path.join(projectRoot, 'scripts', 'build.js'))).toBe(true);
|
|
127
|
+
expect(fs.existsSync(path.join(projectRoot, 'scripts', 'build-svgs.js'))).toBe(true);
|
|
128
|
+
expect(fs.existsSync(path.join(projectRoot, 'scripts', 'build-css.js'))).toBe(true);
|
|
129
|
+
expect(fs.existsSync(path.join(projectRoot, 'scripts', 'build-icon-docs.js'))).toBe(true);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
describe('Webpack configuration', () => {
|
|
134
|
+
it('should have webpack.config.js', () => {
|
|
135
|
+
expect(fs.existsSync(path.join(projectRoot, 'webpack.config.js'))).toBe(true);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
});
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for build-svgs.js
|
|
3
|
+
*
|
|
4
|
+
* Tests SVG file generation from icons.json
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, beforeAll } from 'vitest';
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
|
|
10
|
+
const iconsPath = path.resolve(__dirname, '../src/icons.json');
|
|
11
|
+
const svgDir = path.resolve(__dirname, '../src/svg');
|
|
12
|
+
|
|
13
|
+
describe('build-svgs.js', () => {
|
|
14
|
+
let icons;
|
|
15
|
+
|
|
16
|
+
beforeAll(() => {
|
|
17
|
+
icons = JSON.parse(fs.readFileSync(iconsPath, 'utf8'));
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
describe('icons.json validation', () => {
|
|
21
|
+
it('should be valid JSON array', () => {
|
|
22
|
+
expect(Array.isArray(icons)).toBe(true);
|
|
23
|
+
expect(icons.length).toBeGreaterThan(0);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should have required fields for each icon', () => {
|
|
27
|
+
icons.forEach((icon, index) => {
|
|
28
|
+
expect(icon).toHaveProperty('name', expect.any(String));
|
|
29
|
+
expect(icon).toHaveProperty('slug', expect.any(String));
|
|
30
|
+
expect(icon).toHaveProperty('src', expect.any(String));
|
|
31
|
+
expect(icon).toHaveProperty('tags', expect.any(Array));
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should have unique slugs', () => {
|
|
36
|
+
const slugs = icons.map(icon => icon.slug);
|
|
37
|
+
const uniqueSlugs = [...new Set(slugs)];
|
|
38
|
+
expect(slugs.length).toBe(uniqueSlugs.length);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should have valid SVG path data in src', () => {
|
|
42
|
+
icons.forEach(icon => {
|
|
43
|
+
// SVG path should start with a valid command (M, m, L, l, etc.)
|
|
44
|
+
expect(icon.src).toMatch(/^[MmLlHhVvCcSsQqTtAaZz0-9\s.,\-]+$/);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should have non-empty tags array', () => {
|
|
49
|
+
icons.forEach(icon => {
|
|
50
|
+
expect(icon.tags.length).toBeGreaterThan(0);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('SVG file generation', () => {
|
|
56
|
+
it('should have generated SVG files for all icons', () => {
|
|
57
|
+
icons.forEach(icon => {
|
|
58
|
+
const svgPath = path.join(svgDir, `${icon.slug}.svg`);
|
|
59
|
+
expect(fs.existsSync(svgPath)).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('should generate valid SVG content', () => {
|
|
64
|
+
const sampleIcon = icons[0];
|
|
65
|
+
const svgPath = path.join(svgDir, `${sampleIcon.slug}.svg`);
|
|
66
|
+
const svgContent = fs.readFileSync(svgPath, 'utf8');
|
|
67
|
+
|
|
68
|
+
expect(svgContent).toContain('<svg');
|
|
69
|
+
expect(svgContent).toContain('viewBox=');
|
|
70
|
+
expect(svgContent).toContain('xmlns="http://www.w3.org/2000/svg"');
|
|
71
|
+
expect(svgContent).toContain('<path');
|
|
72
|
+
expect(svgContent).toContain(sampleIcon.src);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('should apply default SVG attributes', () => {
|
|
76
|
+
const svgPath = path.join(svgDir, `${icons[0].slug}.svg`);
|
|
77
|
+
const svgContent = fs.readFileSync(svgPath, 'utf8');
|
|
78
|
+
|
|
79
|
+
// Default values from build-svgs.js
|
|
80
|
+
expect(svgContent).toContain('viewBox="0 0 24 24"');
|
|
81
|
+
expect(svgContent).toContain('fill="none"');
|
|
82
|
+
expect(svgContent).toContain('stroke="currentColor"');
|
|
83
|
+
expect(svgContent).toContain('stroke-width="2"');
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
describe('index.js generation', () => {
|
|
88
|
+
it('should have generated src/svg/index.js', () => {
|
|
89
|
+
const indexPath = path.join(svgDir, 'index.js');
|
|
90
|
+
expect(fs.existsSync(indexPath)).toBe(true);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('should export all icons', () => {
|
|
94
|
+
const indexPath = path.join(svgDir, 'index.js');
|
|
95
|
+
const indexContent = fs.readFileSync(indexPath, 'utf8');
|
|
96
|
+
|
|
97
|
+
icons.forEach(icon => {
|
|
98
|
+
expect(indexContent).toContain(`"${icon.slug}"`);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
});
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for ss-icon.js Web Component
|
|
3
|
+
*
|
|
4
|
+
* Tests the <ss-icon> custom element functionality
|
|
5
|
+
* @vitest-environment jsdom
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect, beforeAll, beforeEach, afterEach } from 'vitest';
|
|
8
|
+
|
|
9
|
+
// Mock the icons module
|
|
10
|
+
const mockIcons = {
|
|
11
|
+
'home': '<svg viewBox="0 0 24 24"><path d="M2.25 12l8.954-8.955"/></svg>',
|
|
12
|
+
'check': '<svg viewBox="0 0 24 24" stroke-width="2"><path d="M4.5 12.75l6 6 9-13.5"/></svg>',
|
|
13
|
+
'plus': '<svg viewBox="0 0 24 24" stroke-width="2"><path d="M12 4.5v15m7.5-7.5h-15"/></svg>'
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// Create a simple mock of the SSIcon class for testing
|
|
17
|
+
class SSIcon extends HTMLElement {
|
|
18
|
+
static get observedAttributes() {
|
|
19
|
+
return ['icon', 'thickness'];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
constructor() {
|
|
23
|
+
super();
|
|
24
|
+
this.attachShadow({ mode: 'open' });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
28
|
+
if (name === 'icon' || name === 'thickness') {
|
|
29
|
+
this.render();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
connectedCallback() {
|
|
34
|
+
this.render();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
render() {
|
|
38
|
+
const iconName = this.getAttribute('icon');
|
|
39
|
+
const iconSvg = mockIcons[iconName];
|
|
40
|
+
|
|
41
|
+
if (!iconSvg) {
|
|
42
|
+
this.shadowRoot.innerHTML = '';
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const thicknessAttr = this.getAttribute('thickness');
|
|
47
|
+
let finalSvg = iconSvg;
|
|
48
|
+
if (thicknessAttr) {
|
|
49
|
+
finalSvg = finalSvg.replace(
|
|
50
|
+
/stroke-width="[^"]*"/,
|
|
51
|
+
`stroke-width="${thicknessAttr}"`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
this.shadowRoot.innerHTML = `
|
|
56
|
+
<style>
|
|
57
|
+
:host {
|
|
58
|
+
display: inline-flex;
|
|
59
|
+
width: 1em;
|
|
60
|
+
height: 1em;
|
|
61
|
+
vertical-align: middle;
|
|
62
|
+
}
|
|
63
|
+
svg {
|
|
64
|
+
width: 100%;
|
|
65
|
+
height: 100%;
|
|
66
|
+
}
|
|
67
|
+
</style>
|
|
68
|
+
${finalSvg}
|
|
69
|
+
`;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
describe('ss-icon.js Web Component', () => {
|
|
74
|
+
beforeAll(() => {
|
|
75
|
+
// Define the custom element
|
|
76
|
+
if (!customElements.get('ss-icon')) {
|
|
77
|
+
customElements.define('ss-icon', SSIcon);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
beforeEach(() => {
|
|
82
|
+
document.body.innerHTML = '';
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
afterEach(() => {
|
|
86
|
+
document.body.innerHTML = '';
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
describe('Custom Element Registration', () => {
|
|
90
|
+
it('should be registered as a custom element', () => {
|
|
91
|
+
expect(customElements.get('ss-icon')).toBeDefined();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should be an instance of HTMLElement', () => {
|
|
95
|
+
const icon = document.createElement('ss-icon');
|
|
96
|
+
expect(icon instanceof HTMLElement).toBe(true);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
describe('Icon Rendering', () => {
|
|
101
|
+
it('should render SVG when icon attribute is set', () => {
|
|
102
|
+
const icon = document.createElement('ss-icon');
|
|
103
|
+
icon.setAttribute('icon', 'home');
|
|
104
|
+
document.body.appendChild(icon);
|
|
105
|
+
|
|
106
|
+
expect(icon.shadowRoot.innerHTML).toContain('<svg');
|
|
107
|
+
expect(icon.shadowRoot.innerHTML).toContain('M2.25 12l8.954-8.955');
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('should render empty when icon attribute is invalid', () => {
|
|
111
|
+
const icon = document.createElement('ss-icon');
|
|
112
|
+
icon.setAttribute('icon', 'nonexistent-icon');
|
|
113
|
+
document.body.appendChild(icon);
|
|
114
|
+
|
|
115
|
+
expect(icon.shadowRoot.querySelector('svg')).toBeNull();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('should render empty when icon attribute is missing', () => {
|
|
119
|
+
const icon = document.createElement('ss-icon');
|
|
120
|
+
document.body.appendChild(icon);
|
|
121
|
+
|
|
122
|
+
expect(icon.shadowRoot.querySelector('svg')).toBeNull();
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('should update when icon attribute changes', () => {
|
|
126
|
+
const icon = document.createElement('ss-icon');
|
|
127
|
+
icon.setAttribute('icon', 'home');
|
|
128
|
+
document.body.appendChild(icon);
|
|
129
|
+
|
|
130
|
+
expect(icon.shadowRoot.innerHTML).toContain('M2.25 12l8.954-8.955');
|
|
131
|
+
|
|
132
|
+
icon.setAttribute('icon', 'check');
|
|
133
|
+
expect(icon.shadowRoot.innerHTML).toContain('M4.5 12.75l6 6 9-13.5');
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
describe('Thickness Attribute', () => {
|
|
138
|
+
it('should apply custom thickness to stroke-width', () => {
|
|
139
|
+
const icon = document.createElement('ss-icon');
|
|
140
|
+
icon.setAttribute('icon', 'check');
|
|
141
|
+
icon.setAttribute('thickness', '3');
|
|
142
|
+
document.body.appendChild(icon);
|
|
143
|
+
|
|
144
|
+
expect(icon.shadowRoot.innerHTML).toContain('stroke-width="3"');
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('should update thickness when attribute changes', () => {
|
|
148
|
+
const icon = document.createElement('ss-icon');
|
|
149
|
+
icon.setAttribute('icon', 'check');
|
|
150
|
+
icon.setAttribute('thickness', '2');
|
|
151
|
+
document.body.appendChild(icon);
|
|
152
|
+
|
|
153
|
+
expect(icon.shadowRoot.innerHTML).toContain('stroke-width="2"');
|
|
154
|
+
|
|
155
|
+
icon.setAttribute('thickness', '4');
|
|
156
|
+
expect(icon.shadowRoot.innerHTML).toContain('stroke-width="4"');
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
describe('Shadow DOM Styles', () => {
|
|
161
|
+
it('should include scoped styles in shadow DOM', () => {
|
|
162
|
+
const icon = document.createElement('ss-icon');
|
|
163
|
+
icon.setAttribute('icon', 'home');
|
|
164
|
+
document.body.appendChild(icon);
|
|
165
|
+
|
|
166
|
+
expect(icon.shadowRoot.innerHTML).toContain('<style>');
|
|
167
|
+
expect(icon.shadowRoot.innerHTML).toContain(':host');
|
|
168
|
+
expect(icon.shadowRoot.innerHTML).toContain('display: inline-flex');
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
describe('Observed Attributes', () => {
|
|
173
|
+
it('should observe icon and thickness attributes', () => {
|
|
174
|
+
expect(SSIcon.observedAttributes).toContain('icon');
|
|
175
|
+
expect(SSIcon.observedAttributes).toContain('thickness');
|
|
176
|
+
});
|
|
177
|
+
});
|
|
178
|
+
});
|