@nimbus-ds/stepper 1.0.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.
Files changed (33) hide show
  1. package/.turbo/turbo-build.log +24 -0
  2. package/CHANGELOG.md +3 -0
  3. package/README.md +125 -0
  4. package/dist/CHANGELOG.md +3 -0
  5. package/dist/README.md +125 -0
  6. package/dist/index.d.ts +850 -0
  7. package/dist/index.js +1 -0
  8. package/package.json +48 -0
  9. package/src/Stepper.tsx +114 -0
  10. package/src/components/StepperCard/StepperCard.tsx +15 -0
  11. package/src/components/StepperCard/index.ts +2 -0
  12. package/src/components/StepperCard/stepperCard.spec.tsx +47 -0
  13. package/src/components/StepperCard/stepperCard.stories.tsx +39 -0
  14. package/src/components/StepperCard/stepperCard.types.ts +11 -0
  15. package/src/components/StepperContext/StepperContext.tsx +9 -0
  16. package/src/components/StepperContext/index.ts +2 -0
  17. package/src/components/StepperContext/stepperContext.spec.tsx +54 -0
  18. package/src/components/StepperContext/stepperContext.types.ts +21 -0
  19. package/src/components/StepperItem/StepperItem.definitions.ts +11 -0
  20. package/src/components/StepperItem/StepperItem.tsx +111 -0
  21. package/src/components/StepperItem/index.ts +2 -0
  22. package/src/components/StepperItem/stepperItem.spec.tsx +572 -0
  23. package/src/components/StepperItem/stepperItem.stories.tsx +60 -0
  24. package/src/components/StepperItem/stepperItem.types.ts +21 -0
  25. package/src/components/index.ts +6 -0
  26. package/src/index.ts +12 -0
  27. package/src/stepper.definitions.ts +11 -0
  28. package/src/stepper.docs.json +68 -0
  29. package/src/stepper.spec.tsx +344 -0
  30. package/src/stepper.stories.tsx +145 -0
  31. package/src/stepper.types.ts +48 -0
  32. package/tsconfig.json +4 -0
  33. package/webpack.config.ts +11 -0
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("react"),require("@nimbus-ds/box"),require("@nimbus-ds/icon"),require("@nimbus-ds/text"),require("@nimbus-ds/icons"),require("@nimbus-ds/styles"),require("@nimbus-ds/title")):"function"==typeof define&&define.amd?define(["react","@nimbus-ds/box","@nimbus-ds/icon","@nimbus-ds/text","@nimbus-ds/icons","@nimbus-ds/styles","@nimbus-ds/title"],t):"object"==typeof exports?exports["@nimbus-ds/stepper"]=t(require("react"),require("@nimbus-ds/box"),require("@nimbus-ds/icon"),require("@nimbus-ds/text"),require("@nimbus-ds/icons"),require("@nimbus-ds/styles"),require("@nimbus-ds/title")):e["@nimbus-ds/stepper"]=t(e.react,e["@nimbus-ds/box"],e["@nimbus-ds/icon"],e["@nimbus-ds/text"],e["@nimbus-ds/icons"],e["@nimbus-ds/styles"],e["@nimbus-ds/title"])}(global,((e,t,r,n,o,a,i)=>(()=>{"use strict";var s={253:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Card=void 0;const n=r(769).__importDefault(r(155)),o=r(367),a=r(190),i=({className:e,style:t,children:r,padding:a="base",backgroundColor:i="neutral-background",...s})=>n.default.createElement("div",{className:[o.card.classnames.container,o.card.sprinkle({padding:a,backgroundColor:i})].join(" "),...s},r);t.Card=i,i.Body=a.CardBody,i.Footer=a.CardFooter,i.Header=a.CardHeader,i.displayName="Card",i.Body.displayName="Card.Body",i.Footer.displayName="Card.Footer",i.Header.displayName="Card.Header"},45:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.CardBody=void 0;const n=r(769).__importDefault(r(155)),o=r(367);t.CardBody=({className:e,style:t,padding:r="none",children:a,...i})=>n.default.createElement("div",{className:o.card.subComponents.body.sprinkle({padding:r}),...i},a)},161:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.CardBody=void 0;const n=r(45);var o=r(45);Object.defineProperty(t,"CardBody",{enumerable:!0,get:function(){return o.CardBody}}),t.default=n.CardBody},719:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.CardFooter=void 0;const n=r(769).__importDefault(r(155)),o=r(367);t.CardFooter=({className:e,style:t,padding:r="none",children:a,...i})=>n.default.createElement("div",{className:[o.card.classnames.container__footer,o.card.subComponents.footer.sprinkle({padding:r})].join(" "),...i},a)},410:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.CardFooter=void 0;const n=r(719);var o=r(719);Object.defineProperty(t,"CardFooter",{enumerable:!0,get:function(){return o.CardFooter}}),t.default=n.CardFooter},407:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.CardHeader=void 0;const n=r(769).__importDefault(r(155)),o=r(593),a=r(367);t.CardHeader=({className:e,style:t,padding:r="none",title:i,children:s,...l})=>n.default.createElement("div",{className:a.card.subComponents.header.sprinkle({padding:r}),...l},i&&n.default.createElement(o.Title,{"data-testid":"header-title",as:"h4"},i),s)},348:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.CardHeader=void 0;const n=r(407);var o=r(407);Object.defineProperty(t,"CardHeader",{enumerable:!0,get:function(){return o.CardHeader}}),t.default=n.CardHeader},190:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0});const n=r(769);n.__exportStar(r(161),t),n.__exportStar(r(410),t),n.__exportStar(r(348),t)},509:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Card=void 0;const n=r(253);var o=r(253);Object.defineProperty(t,"Card",{enumerable:!0,get:function(){return o.Card}}),t.default=n.Card},831:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Stepper=void 0;const n=r(769).__importStar(r(155)),o=r(558),a=r(337),i=r(317),s=Object.assign((({activeStep:e,children:t,...r})=>{const s=(0,n.useMemo)((()=>(0,i.isControlled)(r)),[r]),[l,c]=(0,n.useState)(e),u=s?r.selectedStep:l,p=s?r.onSelectStep:c,d=n.default.Children.count(t),f=n.default.Children.map(t,((e,t)=>{if(n.default.isValidElement(e)){const r=t;return n.default.cloneElement(e,{step:r})}return e}));(0,n.useEffect)((()=>{s||c(e)}),[e,s]);const y=(0,n.useMemo)((()=>{if(s){const{selectedStep:e,onSelectStep:t,...n}=r;return n}return r}),[r,s]),m=(0,n.useMemo)((()=>({totalSteps:d,activeStep:e,selectedStep:u,onSelect:p})),[d,e,u,p]);return n.default.createElement(a.StepperContext.Provider,{value:m},n.default.createElement(o.Box,{display:"flex",flexWrap:"wrap",gap:"2",justifyContent:"center",alignItems:"center",role:"progressbar","aria-valuenow":e+1,"aria-valuemin":1,"aria-valuemax":d,"aria-label":`Multi-step process: Step ${e+1} of ${d}`,...y},f))}),{Item:a.StepperItem,Card:a.StepperCard,displayName:"Stepper"});t.Stepper=s,s.Item.displayName="Stepper.Item",s.Card.displayName="Stepper.Card"},566:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.StepperCard=void 0;const n=r(769).__importDefault(r(155)),o=r(509),a=({children:e})=>n.default.createElement(o.Card,{padding:"small"},e);t.StepperCard=a,a.displayName="Stepper.Card"},613:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.StepperCard=void 0;var n=r(566);Object.defineProperty(t,"StepperCard",{enumerable:!0,get:function(){return n.StepperCard}})},980:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.StepperContext=void 0;const n=r(155);t.StepperContext=(0,n.createContext)({totalSteps:1,activeStep:0,selectedStep:void 0,onSelect:void 0})},462:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.StepperContext=void 0;var n=r(980);Object.defineProperty(t,"StepperContext",{enumerable:!0,get:function(){return n.StepperContext}})},702:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.StepperItemState=t.joinClassNames=void 0;t.joinClassNames=(...e)=>e.filter(Boolean).join(" "),function(e){e.STARTED="started",e.COMPLETED="completed",e.SELECTED="selected",e.PENDING="pending"}(t.StepperItemState||(t.StepperItemState={}))},90:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.StepperItem=void 0;const n=r(769).__importStar(r(155)),o=r(208),a=r(526),i=r(809),s=r(367),l=r(462),c=r(702),u=({className:e,style:t,step:r,label:u,...p})=>{const{totalSteps:d,activeStep:f,selectedStep:y,onSelect:m}=(0,n.useContext)(l.StepperContext),_=(0,n.useMemo)((()=>y===r?c.StepperItemState.SELECTED:r===f?c.StepperItemState.STARTED:r<f?c.StepperItemState.COMPLETED:c.StepperItemState.PENDING),[f,y,r]),b=_===c.StepperItemState.PENDING,v=_===c.StepperItemState.SELECTED,S=_===c.StepperItemState.COMPLETED,h=r===d-1,C=e=>{e&&"Enter"!==e.key&&" "!==e.key||(e?.preventDefault(),!m||b||v||m(r))},w=(0,n.useCallback)((()=>S?n.default.createElement(o.Icon,{source:n.default.createElement(i.CheckCircleIcon,{size:"small"}),color:"success-textHigh"}):n.default.createElement(a.Text,{as:"span",color:"currentColor",fontSize:"caption",fontWeight:"medium"},r+1)),[S,r]);return n.default.createElement(n.default.Fragment,null,n.default.createElement("div",{className:(0,c.joinClassNames)(s.stepper.classnames.item,(b||v)&&s.stepper.classnames.item__disabled),role:"button",tabIndex:m?0:-1,onKeyDown:C,onClick:()=>C(),...p},n.default.createElement("div",{className:(0,c.joinClassNames)(s.stepper.classnames.item__icon,s.stepper.classnames[`item__icon_${_}`])},w()),u&&n.default.createElement("span",{className:(0,c.joinClassNames)(s.stepper.classnames.item__label,s.stepper.classnames[`item__label_${_}`])},u)),!h&&n.default.createElement("div",{className:s.stepper.classnames.item__line}))};t.StepperItem=u,u.displayName="Stepper.Item"},976:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.StepperItem=void 0;var n=r(90);Object.defineProperty(t,"StepperItem",{enumerable:!0,get:function(){return n.StepperItem}})},337:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.StepperContext=t.StepperCard=t.StepperItem=void 0;var n=r(976);Object.defineProperty(t,"StepperItem",{enumerable:!0,get:function(){return n.StepperItem}});var o=r(613);Object.defineProperty(t,"StepperCard",{enumerable:!0,get:function(){return o.StepperCard}});var a=r(462);Object.defineProperty(t,"StepperContext",{enumerable:!0,get:function(){return a.StepperContext}})},317:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.isControlled=void 0;t.isControlled=e=>"selectedStep"in e&&"onSelectStep"in e},558:e=>{e.exports=t},208:e=>{e.exports=r},809:e=>{e.exports=o},367:e=>{e.exports=a},526:e=>{e.exports=n},593:e=>{e.exports=i},155:t=>{t.exports=e},769:(e,t,r)=>{r.r(t),r.d(t,{__addDisposableResource:()=>k,__assign:()=>a,__asyncDelegator:()=>O,__asyncGenerator:()=>j,__asyncValues:()=>P,__await:()=>g,__awaiter:()=>y,__classPrivateFieldGet:()=>T,__classPrivateFieldIn:()=>D,__classPrivateFieldSet:()=>M,__createBinding:()=>_,__decorate:()=>s,__disposeResources:()=>q,__esDecorate:()=>c,__exportStar:()=>b,__extends:()=>o,__generator:()=>m,__importDefault:()=>N,__importStar:()=>I,__makeTemplateObject:()=>x,__metadata:()=>f,__param:()=>l,__propKey:()=>p,__read:()=>S,__rest:()=>i,__runInitializers:()=>u,__setFunctionName:()=>d,__spread:()=>h,__spreadArray:()=>w,__spreadArrays:()=>C,__values:()=>v,default:()=>B});var n=function(e,t){return n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var r in t)Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r])},n(e,t)};function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function r(){this.constructor=e}n(e,t),e.prototype=null===t?Object.create(t):(r.prototype=t.prototype,new r)}var a=function(){return a=Object.assign||function(e){for(var t,r=1,n=arguments.length;r<n;r++)for(var o in t=arguments[r])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},a.apply(this,arguments)};function i(e,t){var r={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(n=Object.getOwnPropertySymbols(e);o<n.length;o++)t.indexOf(n[o])<0&&Object.prototype.propertyIsEnumerable.call(e,n[o])&&(r[n[o]]=e[n[o]])}return r}function s(e,t,r,n){var o,a=arguments.length,i=a<3?t:null===n?n=Object.getOwnPropertyDescriptor(t,r):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)i=Reflect.decorate(e,t,r,n);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(i=(a<3?o(i):a>3?o(t,r,i):o(t,r))||i);return a>3&&i&&Object.defineProperty(t,r,i),i}function l(e,t){return function(r,n){t(r,n,e)}}function c(e,t,r,n,o,a){function i(e){if(void 0!==e&&"function"!=typeof e)throw new TypeError("Function expected");return e}for(var s,l=n.kind,c="getter"===l?"get":"setter"===l?"set":"value",u=!t&&e?n.static?e:e.prototype:null,p=t||(u?Object.getOwnPropertyDescriptor(u,n.name):{}),d=!1,f=r.length-1;f>=0;f--){var y={};for(var m in n)y[m]="access"===m?{}:n[m];for(var m in n.access)y.access[m]=n.access[m];y.addInitializer=function(e){if(d)throw new TypeError("Cannot add initializers after decoration has completed");a.push(i(e||null))};var _=(0,r[f])("accessor"===l?{get:p.get,set:p.set}:p[c],y);if("accessor"===l){if(void 0===_)continue;if(null===_||"object"!=typeof _)throw new TypeError("Object expected");(s=i(_.get))&&(p.get=s),(s=i(_.set))&&(p.set=s),(s=i(_.init))&&o.unshift(s)}else(s=i(_))&&("field"===l?o.unshift(s):p[c]=s)}u&&Object.defineProperty(u,n.name,p),d=!0}function u(e,t,r){for(var n=arguments.length>2,o=0;o<t.length;o++)r=n?t[o].call(e,r):t[o].call(e);return n?r:void 0}function p(e){return"symbol"==typeof e?e:"".concat(e)}function d(e,t,r){return"symbol"==typeof t&&(t=t.description?"[".concat(t.description,"]"):""),Object.defineProperty(e,"name",{configurable:!0,value:r?"".concat(r," ",t):t})}function f(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function y(e,t,r,n){return new(r||(r=Promise))((function(o,a){function i(e){try{l(n.next(e))}catch(e){a(e)}}function s(e){try{l(n.throw(e))}catch(e){a(e)}}function l(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(i,s)}l((n=n.apply(e,t||[])).next())}))}function m(e,t){var r,n,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(s){return function(l){return function(s){if(r)throw new TypeError("Generator is already executing.");for(;a&&(a=0,s[0]&&(i=0)),i;)try{if(r=1,n&&(o=2&s[0]?n.return:s[0]?n.throw||((o=n.return)&&o.call(n),0):n.next)&&!(o=o.call(n,s[1])).done)return o;switch(n=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return i.label++,{value:s[1],done:!1};case 5:i.label++,n=s[1],s=[0];continue;case 7:s=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]<o[3])){i.label=s[1];break}if(6===s[0]&&i.label<o[1]){i.label=o[1],o=s;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(s);break}o[2]&&i.ops.pop(),i.trys.pop();continue}s=t.call(e,i)}catch(e){s=[6,e],n=0}finally{r=o=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}([s,l])}}}var _=Object.create?function(e,t,r,n){void 0===n&&(n=r);var o=Object.getOwnPropertyDescriptor(t,r);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[r]}}),Object.defineProperty(e,n,o)}:function(e,t,r,n){void 0===n&&(n=r),e[n]=t[r]};function b(e,t){for(var r in e)"default"===r||Object.prototype.hasOwnProperty.call(t,r)||_(t,e,r)}function v(e){var t="function"==typeof Symbol&&Symbol.iterator,r=t&&e[t],n=0;if(r)return r.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&n>=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function S(e,t){var r="function"==typeof Symbol&&e[Symbol.iterator];if(!r)return e;var n,o,a=r.call(e),i=[];try{for(;(void 0===t||t-- >0)&&!(n=a.next()).done;)i.push(n.value)}catch(e){o={error:e}}finally{try{n&&!n.done&&(r=a.return)&&r.call(a)}finally{if(o)throw o.error}}return i}function h(){for(var e=[],t=0;t<arguments.length;t++)e=e.concat(S(arguments[t]));return e}function C(){for(var e=0,t=0,r=arguments.length;t<r;t++)e+=arguments[t].length;var n=Array(e),o=0;for(t=0;t<r;t++)for(var a=arguments[t],i=0,s=a.length;i<s;i++,o++)n[o]=a[i];return n}function w(e,t,r){if(r||2===arguments.length)for(var n,o=0,a=t.length;o<a;o++)!n&&o in t||(n||(n=Array.prototype.slice.call(t,0,o)),n[o]=t[o]);return e.concat(n||Array.prototype.slice.call(t))}function g(e){return this instanceof g?(this.v=e,this):new g(e)}function j(e,t,r){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var n,o=r.apply(e,t||[]),a=[];return n={},i("next"),i("throw"),i("return"),n[Symbol.asyncIterator]=function(){return this},n;function i(e){o[e]&&(n[e]=function(t){return new Promise((function(r,n){a.push([e,t,r,n])>1||s(e,t)}))})}function s(e,t){try{(r=o[e](t)).value instanceof g?Promise.resolve(r.value.v).then(l,c):u(a[0][2],r)}catch(e){u(a[0][3],e)}var r}function l(e){s("next",e)}function c(e){s("throw",e)}function u(e,t){e(t),a.shift(),a.length&&s(a[0][0],a[0][1])}}function O(e){var t,r;return t={},n("next"),n("throw",(function(e){throw e})),n("return"),t[Symbol.iterator]=function(){return this},t;function n(n,o){t[n]=e[n]?function(t){return(r=!r)?{value:g(e[n](t)),done:!1}:o?o(t):t}:o}}function P(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,r=e[Symbol.asyncIterator];return r?r.call(e):(e=v(e),t={},n("next"),n("throw"),n("return"),t[Symbol.asyncIterator]=function(){return this},t);function n(r){t[r]=e[r]&&function(t){return new Promise((function(n,o){(function(e,t,r,n){Promise.resolve(n).then((function(t){e({value:t,done:r})}),t)})(n,o,(t=e[r](t)).done,t.value)}))}}}function x(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e}var E=Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t};function I(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var r in e)"default"!==r&&Object.prototype.hasOwnProperty.call(e,r)&&_(t,e,r);return E(t,e),t}function N(e){return e&&e.__esModule?e:{default:e}}function T(e,t,r,n){if("a"===r&&!n)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!n:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===r?n:"a"===r?n.call(e):n?n.value:t.get(e)}function M(e,t,r,n,o){if("m"===n)throw new TypeError("Private method is not writable");if("a"===n&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!o:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===n?o.call(e,r):o?o.value=r:t.set(e,r),r}function D(e,t){if(null===t||"object"!=typeof t&&"function"!=typeof t)throw new TypeError("Cannot use 'in' operator on non-object");return"function"==typeof e?t===e:e.has(t)}function k(e,t,r){if(null!=t){if("object"!=typeof t&&"function"!=typeof t)throw new TypeError("Object expected.");var n;if(r){if(!Symbol.asyncDispose)throw new TypeError("Symbol.asyncDispose is not defined.");n=t[Symbol.asyncDispose]}if(void 0===n){if(!Symbol.dispose)throw new TypeError("Symbol.dispose is not defined.");n=t[Symbol.dispose]}if("function"!=typeof n)throw new TypeError("Object not disposable.");e.stack.push({value:t,dispose:n,async:r})}else r&&e.stack.push({async:!0});return t}var F="function"==typeof SuppressedError?SuppressedError:function(e,t,r){var n=new Error(r);return n.name="SuppressedError",n.error=e,n.suppressed=t,n};function q(e){function t(t){e.error=e.hasError?new F(t,e.error,"An error was suppressed during disposal."):t,e.hasError=!0}return function r(){for(;e.stack.length;){var n=e.stack.pop();try{var o=n.dispose&&n.dispose.call(n.value);if(n.async)return Promise.resolve(o).then(r,(function(e){return t(e),r()}))}catch(e){t(e)}}if(e.hasError)throw e.error}()}const B={__extends:o,__assign:a,__rest:i,__decorate:s,__param:l,__metadata:f,__awaiter:y,__generator:m,__createBinding:_,__exportStar:b,__values:v,__read:S,__spread:h,__spreadArrays:C,__spreadArray:w,__await:g,__asyncGenerator:j,__asyncDelegator:O,__asyncValues:P,__makeTemplateObject:x,__importStar:I,__importDefault:N,__classPrivateFieldGet:T,__classPrivateFieldSet:M,__classPrivateFieldIn:D,__addDisposableResource:k,__disposeResources:q}}},l={};function c(e){var t=l[e];if(void 0!==t)return t.exports;var r=l[e]={exports:{}};return s[e](r,r.exports,c),r.exports}c.d=(e,t)=>{for(var r in t)c.o(t,r)&&!c.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},c.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),c.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var u={};return(()=>{var e=u;Object.defineProperty(e,"__esModule",{value:!0}),e.isControlled=e.Stepper=void 0;var t=c(831);Object.defineProperty(e,"Stepper",{enumerable:!0,get:function(){return t.Stepper}});var r=c(317);Object.defineProperty(e,"isControlled",{enumerable:!0,get:function(){return r.isControlled}})})(),u})()));
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@nimbus-ds/stepper",
3
+ "version": "1.0.0",
4
+ "description": "Stepper component for guiding users through multi-step processes",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.esm.js",
7
+ "types": "dist/index.d.ts",
8
+ "license": "MIT",
9
+ "keywords": [
10
+ "nimbus",
11
+ "design-system",
12
+ "react",
13
+ "stepper",
14
+ "progress",
15
+ "steps",
16
+ "wizard"
17
+ ],
18
+ "scripts": {
19
+ "build": "yarn g:webpack",
20
+ "clean": "rm -rf dist",
21
+ "version": "yarn version"
22
+ },
23
+ "homepage": "https://nimbus.nuvemshop.com.br",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/TiendaNube/nimbus-design-system.git",
27
+ "directory": "packages/react/src/composite/Stepper"
28
+ },
29
+ "bugs": {
30
+ "url": "https://github.com/TiendaNube/nimbus-design-system/issues"
31
+ },
32
+ "dependencies": {
33
+ "@nimbus-ds/box": "^4.2.0",
34
+ "@nimbus-ds/card": "^3.1.2",
35
+ "@nimbus-ds/icon": "^3.0.1",
36
+ "@nimbus-ds/icons": "^1.9.0",
37
+ "@nimbus-ds/styles": "^9.16.0",
38
+ "@nimbus-ds/text": "^6.4.0"
39
+ },
40
+ "peerDependencies": {
41
+ "react": "^16.8 || ^17.0 || ^18.0",
42
+ "react-dom": "^16.8 || ^17.0 || ^18.0"
43
+ },
44
+ "devDependencies": {
45
+ "@nimbus-ds/button": "^2.6.0",
46
+ "@nimbus-ds/webpack": "^1.5.1"
47
+ }
48
+ }
@@ -0,0 +1,114 @@
1
+ import React, { useEffect, useMemo, useState } from "react";
2
+
3
+ import { Box, BoxProps } from "@nimbus-ds/box";
4
+ import {
5
+ StepperProps,
6
+ StepperComponents,
7
+ ControlledStepperProperties,
8
+ } from "./stepper.types";
9
+ import { StepperItem, StepperCard, StepperContext } from "./components";
10
+ import { isControlled } from "./stepper.definitions";
11
+ import { StepperItemProps } from "./components/StepperItem/stepperItem.types";
12
+
13
+ /**
14
+ * Stepper component guides users through a multi-step process,
15
+ * showing their progress and allowing navigation between completed steps.
16
+ * Total steps are automatically calculated based on the number of children.
17
+ * Step numbers are automatically assigned based on child position.
18
+ */
19
+ const StepperComponent: React.FC<StepperProps> = ({
20
+ activeStep,
21
+ children,
22
+ ...rest
23
+ }: StepperProps) => {
24
+ // Memoize controlled mode check to avoid recalculation on every render
25
+ const isControlledMode = useMemo(() => isControlled(rest), [rest]);
26
+
27
+ // Internal state for uncontrolled mode
28
+ const [internalSelectedStep, setInternalSelectedStep] =
29
+ useState<number>(activeStep);
30
+
31
+ // Determine current selected step and handler based on control mode
32
+ const selectedStep = isControlledMode
33
+ ? (rest as ControlledStepperProperties).selectedStep
34
+ : internalSelectedStep;
35
+
36
+ const handleSelect = isControlledMode
37
+ ? (rest as ControlledStepperProperties).onSelectStep
38
+ : setInternalSelectedStep;
39
+
40
+ const totalSteps = React.Children.count(children);
41
+
42
+ // Map children to automatically assign step numbers
43
+ const mappedChildren = React.Children.map(children, (child, index) => {
44
+ if (React.isValidElement(child)) {
45
+ const stepIndex = index;
46
+ return React.cloneElement(child, { step: stepIndex } as StepperItemProps);
47
+ }
48
+ return child;
49
+ });
50
+
51
+ // Sync internal selected step with active step in uncontrolled mode
52
+ useEffect(() => {
53
+ if (!isControlledMode) {
54
+ setInternalSelectedStep(activeStep);
55
+ }
56
+ }, [activeStep, isControlledMode]);
57
+
58
+ // Extract controlled properties from rest to avoid passing them to Box
59
+ const containerProps = useMemo(() => {
60
+ if (isControlledMode) {
61
+ const {
62
+ selectedStep: _,
63
+ onSelectStep: __,
64
+ ...boxProps
65
+ } = rest as ControlledStepperProperties & BoxProps;
66
+ return boxProps;
67
+ }
68
+ return rest as BoxProps;
69
+ }, [rest, isControlledMode]);
70
+
71
+ const contextValue = useMemo(
72
+ () => ({
73
+ totalSteps,
74
+ activeStep,
75
+ selectedStep,
76
+ onSelect: handleSelect,
77
+ }),
78
+ [totalSteps, activeStep, selectedStep, handleSelect]
79
+ );
80
+
81
+ return (
82
+ <StepperContext.Provider value={contextValue}>
83
+ <Box
84
+ display="flex"
85
+ flexWrap="wrap"
86
+ gap="2"
87
+ justifyContent="center"
88
+ alignItems="center"
89
+ role="progressbar"
90
+ aria-valuenow={activeStep + 1}
91
+ aria-valuemin={1}
92
+ aria-valuemax={totalSteps}
93
+ aria-label={`Multi-step process: Step ${
94
+ activeStep + 1
95
+ } of ${totalSteps}`}
96
+ {...containerProps}
97
+ >
98
+ {mappedChildren}
99
+ </Box>
100
+ </StepperContext.Provider>
101
+ );
102
+ };
103
+
104
+ // Assign static properties using Object.assign to avoid complex typing issues
105
+ const Stepper = Object.assign(StepperComponent, {
106
+ Item: StepperItem,
107
+ Card: StepperCard,
108
+ displayName: "Stepper",
109
+ }) as React.FC<StepperProps> & StepperComponents;
110
+
111
+ Stepper.Item.displayName = "Stepper.Item";
112
+ Stepper.Card.displayName = "Stepper.Card";
113
+
114
+ export { Stepper };
@@ -0,0 +1,15 @@
1
+ import React from "react";
2
+ import { Card } from "@nimbus-ds/card";
3
+
4
+ import { StepperCardProps } from "./stepperCard.types";
5
+
6
+ /**
7
+ * StepperCard is a container component that wraps content in a Card component.
8
+ * It provides consistent styling and spacing for stepper-related content.
9
+ * Uses the design system's Card component with small padding for optimal layout.
10
+ */
11
+ const StepperCard: React.FC<StepperCardProps> = ({ children }) => <Card padding="small">{children}</Card>;
12
+
13
+ StepperCard.displayName = "Stepper.Card";
14
+
15
+ export { StepperCard };
@@ -0,0 +1,2 @@
1
+ export { StepperCard } from "./StepperCard";
2
+ export type { StepperCardProps } from "./stepperCard.types";
@@ -0,0 +1,47 @@
1
+ import React from "react";
2
+ import { render, screen } from "@testing-library/react";
3
+
4
+ import { StepperCard } from "./StepperCard";
5
+
6
+ describe("GIVEN <StepperCard />", () => {
7
+ describe("WHEN rendered", () => {
8
+ it("THEN should render children correctly", () => {
9
+ render(
10
+ <StepperCard>
11
+ <div data-testid="test-content">Test Content</div>
12
+ </StepperCard>
13
+ );
14
+
15
+ expect(screen.getByTestId("test-content")).toBeInTheDocument();
16
+ expect(screen.getByText("Test Content")).toBeInTheDocument();
17
+ });
18
+
19
+ it("THEN should apply correct display name", () => {
20
+ expect(StepperCard.displayName).toBe("Stepper.Card");
21
+ });
22
+ });
23
+
24
+ describe("WHEN rendered with multiple children", () => {
25
+ it("THEN should render all children", () => {
26
+ render(
27
+ <StepperCard>
28
+ <div data-testid="child-1">Child 1</div>
29
+ <div data-testid="child-2">Child 2</div>
30
+ <span data-testid="child-3">Child 3</span>
31
+ </StepperCard>
32
+ );
33
+
34
+ expect(screen.getByTestId("child-1")).toBeInTheDocument();
35
+ expect(screen.getByTestId("child-2")).toBeInTheDocument();
36
+ expect(screen.getByTestId("child-3")).toBeInTheDocument();
37
+ });
38
+ });
39
+
40
+ describe("WHEN rendered with empty children", () => {
41
+ it("THEN should render empty card", () => {
42
+ const { container } = render(<StepperCard>{null}</StepperCard>);
43
+
44
+ expect(container.firstChild).toBeInTheDocument();
45
+ });
46
+ });
47
+ });
@@ -0,0 +1,39 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import React from "react";
3
+
4
+ import { Text } from "@nimbus-ds/text";
5
+ import { Box } from "@nimbus-ds/box";
6
+ import { StepperCard } from "./StepperCard";
7
+
8
+ const meta: Meta<typeof StepperCard> = {
9
+ title: "Composite/Stepper/StepperCard",
10
+ component: StepperCard,
11
+ tags: ["autodocs"],
12
+ };
13
+
14
+ export default meta;
15
+
16
+ type Story = StoryObj<typeof StepperCard>;
17
+
18
+ export const Basic: Story = {
19
+ render: () => (
20
+ <StepperCard>
21
+ <Text>This content is wrapped in a Card with small padding</Text>
22
+ </StepperCard>
23
+ ),
24
+ };
25
+
26
+ export const WithMultipleElements: Story = {
27
+ render: () => (
28
+ <StepperCard>
29
+ <Box display="flex" flexDirection="column" gap="2">
30
+ <Text fontSize="base" fontWeight="medium">
31
+ Card Container Example
32
+ </Text>
33
+ <Text fontSize="caption" color="neutral-textLow">
34
+ This demonstrates the StepperCard component wrapping multiple elements.
35
+ </Text>
36
+ </Box>
37
+ </StepperCard>
38
+ ),
39
+ };
@@ -0,0 +1,11 @@
1
+ import { ReactNode } from "react";
2
+
3
+ export interface StepperCardProperties {
4
+ /**
5
+ * The content to be rendered inside the card container
6
+ * @TJS-type React.ReactNode
7
+ */
8
+ children: ReactNode;
9
+ }
10
+
11
+ export type StepperCardProps = StepperCardProperties;
@@ -0,0 +1,9 @@
1
+ import { createContext } from "react";
2
+ import { StepperContextValue } from "./stepperContext.types";
3
+
4
+ export const StepperContext = createContext<StepperContextValue>({
5
+ totalSteps: 1,
6
+ activeStep: 0,
7
+ selectedStep: undefined,
8
+ onSelect: undefined,
9
+ });
@@ -0,0 +1,2 @@
1
+ export { StepperContext } from "./StepperContext";
2
+ export type { StepperContextValue } from "./stepperContext.types";
@@ -0,0 +1,54 @@
1
+ import React, { useContext } from "react";
2
+ import { render, screen } from "@testing-library/react";
3
+ import "@testing-library/jest-dom";
4
+ import { StepperContext } from "./StepperContext";
5
+ import { StepperContextValue } from "./stepperContext.types";
6
+
7
+ // Test component that consumes the context
8
+ const TestConsumer = () => {
9
+ const contextValue = useContext(StepperContext);
10
+ return (
11
+ <div data-testid="context-consumer">
12
+ <span data-testid="total-steps">{contextValue.totalSteps}</span>
13
+ </div>
14
+ );
15
+ };
16
+
17
+ const makeSut = (value: StepperContextValue) => {
18
+ render(
19
+ <StepperContext.Provider value={value}>
20
+ <TestConsumer />
21
+ </StepperContext.Provider>
22
+ );
23
+ };
24
+
25
+ describe("GIVEN <StepperContext />", () => {
26
+ describe("WHEN providing context value", () => {
27
+ it("THEN should provide totalSteps to consuming components", () => {
28
+ makeSut({ totalSteps: 5, activeStep: 1, selectedStep: 1 });
29
+
30
+ expect(screen.getByTestId("total-steps")).toHaveTextContent("5");
31
+ });
32
+
33
+ it("THEN should handle single step scenario", () => {
34
+ makeSut({ totalSteps: 1, activeStep: 1, selectedStep: 1 });
35
+
36
+ expect(screen.getByTestId("total-steps")).toHaveTextContent("1");
37
+ });
38
+
39
+ it("THEN should handle many steps scenario", () => {
40
+ makeSut({ totalSteps: 10, activeStep: 1, selectedStep: 1 });
41
+
42
+ expect(screen.getByTestId("total-steps")).toHaveTextContent("10");
43
+ });
44
+ });
45
+
46
+ describe("WHEN no provider is present", () => {
47
+ it("THEN should use default context value", () => {
48
+ render(<TestConsumer />);
49
+
50
+ // Default value should be 1 as defined in StepperContext
51
+ expect(screen.getByTestId("total-steps")).toHaveTextContent("1");
52
+ });
53
+ });
54
+ });
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Context value provided by StepperContext to share state between stepper components
3
+ */
4
+ export interface StepperContextValue {
5
+ /**
6
+ * The total number of steps in the stepper
7
+ */
8
+ totalSteps: number;
9
+ /**
10
+ * The currently active step (0-based index)
11
+ */
12
+ activeStep: number;
13
+ /**
14
+ * The currently selected step (0-based index)
15
+ */
16
+ selectedStep?: number;
17
+ /**
18
+ * Callback to handle step selection
19
+ */
20
+ onSelect?: (step: number) => void;
21
+ }
@@ -0,0 +1,11 @@
1
+ // Utility function to join class names, filtering out empty strings
2
+ export const joinClassNames = (
3
+ ...classNames: (string | false | undefined)[]
4
+ ): string => classNames.filter(Boolean).join(" ");
5
+
6
+ export enum StepperItemState {
7
+ STARTED = "started",
8
+ COMPLETED = "completed",
9
+ SELECTED = "selected",
10
+ PENDING = "pending",
11
+ }
@@ -0,0 +1,111 @@
1
+ import React, { useCallback, useContext, useMemo } from "react";
2
+ import { Icon } from "@nimbus-ds/icon";
3
+ import { Text } from "@nimbus-ds/text";
4
+ import { CheckCircleIcon } from "@nimbus-ds/icons";
5
+ import { stepper } from "@nimbus-ds/styles";
6
+
7
+ import { StepperItemProps } from "./stepperItem.types";
8
+ import { StepperContext } from "../StepperContext";
9
+ import { joinClassNames, StepperItemState } from "./StepperItem.definitions";
10
+
11
+ /**
12
+ * StepperItem represents a single step in the stepper component.
13
+ * It displays the step number or check icon, label, and connecting line.
14
+ */
15
+ const StepperItem: React.FC<StepperItemProps> = ({
16
+ className: _className,
17
+ style: _style,
18
+ step,
19
+ label,
20
+ ...rest
21
+ }: StepperItemProps) => {
22
+ const { totalSteps, activeStep, selectedStep, onSelect } =
23
+ useContext(StepperContext);
24
+
25
+ // Determine step state based on context
26
+ const stepState = useMemo(() => {
27
+ if (selectedStep === step) return StepperItemState.SELECTED;
28
+ if (step === activeStep) return StepperItemState.STARTED;
29
+ if (step < activeStep) return StepperItemState.COMPLETED;
30
+ return StepperItemState.PENDING;
31
+ }, [activeStep, selectedStep, step]);
32
+
33
+ const isPendingStep = stepState === StepperItemState.PENDING;
34
+ const isSelectedStep = stepState === StepperItemState.SELECTED;
35
+ const isCompletedStep = stepState === StepperItemState.COMPLETED;
36
+ const isLastStep = step === totalSteps - 1;
37
+
38
+ const handleInteraction = (event?: React.KeyboardEvent) => {
39
+ if (event && event.key !== "Enter" && event.key !== " ") return;
40
+
41
+ event?.preventDefault();
42
+
43
+ // Only allow interaction with non-pending and non-selected steps
44
+ if (onSelect && !isPendingStep && !isSelectedStep) {
45
+ onSelect(step);
46
+ }
47
+ };
48
+
49
+ const renderStepIcon = useCallback(() => {
50
+ if (isCompletedStep) {
51
+ return (
52
+ <Icon
53
+ source={<CheckCircleIcon size="small" />}
54
+ color="success-textHigh"
55
+ />
56
+ );
57
+ }
58
+
59
+ return (
60
+ <Text
61
+ as="span"
62
+ color="currentColor" // Inherits color from parent item state classes
63
+ fontSize="caption"
64
+ fontWeight="medium"
65
+ >
66
+ {step + 1}
67
+ </Text>
68
+ );
69
+ }, [isCompletedStep, step]);
70
+
71
+ return (
72
+ <>
73
+ <div
74
+ className={joinClassNames(
75
+ stepper.classnames.item,
76
+ (isPendingStep || isSelectedStep) && stepper.classnames.item__disabled
77
+ )}
78
+ role="button"
79
+ tabIndex={onSelect ? 0 : -1}
80
+ onKeyDown={handleInteraction}
81
+ onClick={() => handleInteraction()}
82
+ {...rest}
83
+ >
84
+ <div
85
+ className={joinClassNames(
86
+ stepper.classnames.item__icon,
87
+ stepper.classnames[`item__icon_${stepState}`]
88
+ )}
89
+ >
90
+ {renderStepIcon()}
91
+ </div>
92
+
93
+ {label && (
94
+ <span
95
+ className={joinClassNames(
96
+ stepper.classnames.item__label,
97
+ stepper.classnames[`item__label_${stepState}`]
98
+ )}
99
+ >
100
+ {label}
101
+ </span>
102
+ )}
103
+ </div>
104
+ {!isLastStep && <div className={stepper.classnames.item__line} />}
105
+ </>
106
+ );
107
+ };
108
+
109
+ StepperItem.displayName = "Stepper.Item";
110
+
111
+ export { StepperItem };
@@ -0,0 +1,2 @@
1
+ export { StepperItem } from "./StepperItem";
2
+ export type { StepperItemProps, StepperItemProperties, StepState } from "./stepperItem.types";