1
0
Fork 0

wip(markdown): Dev docs update for v3

This commit is contained in:
joostdecock 2022-09-21 12:28:58 +02:00
parent 65b053ac1c
commit 6e35a96030
27 changed files with 375 additions and 865 deletions

View file

@ -1,59 +0,0 @@
---
title: Part.addCut()
---
A part's `addCut()` method allows designers to specify how the part should be cut.
It can also be used to remove cutting information, as an alternative
to [Part.removeCut()](/reference/api/part/removecut).
## Part.addCut() signature when adding cut information
```js
Part.part.addCut(cut=2, material='fabric', identical=false)
```
In this form, this methiod takes three parameters:
| Parameter | type | description | default |
| --------- | ---- | ----------- | ------- |
| `cut` | integer | The amount of times this part should be cut. | `2` |
| `material` | string | The name of the material, typically one of `fabric`, `lining`, `facing`, `interfacing`, `canvas`, or `various` | `fabric` |
| `identical` | boolean | Whether or not parts should be cut identical (true) or mirrored (false). Mirorred is often referred to as _good sides together_ | `false` |
## Part.addCut() signature when removing cut information
```js
Part.part.addCut(false, material='fabric')
```
In this form, this methiod takes two parameters:
| Parameter | type | description | default |
| --------- | ---- | ----------- | ------- |
| `cut` | `boolean` | Pass `false` to remove the cut info for the material passed as the second parameter | `2` |
| `material` | string | The name of the material, typically one of `fabric`, `lining`, `facing`, `interfacing`, `canvas`, or `various` | `fabric` |
## Part.addCut() example
```js
export default function (part) {
// Cut two from fabric with good sides together
part.addCut(2, 'fabric')
// Cut seven from lining, identical
part.addCut(7, 'lining')
// Remove the lining cut info (but keep the fabric info)
part.addCut(false, 'lining')
// You would do more useful stuff before returning
return part
}
```
<Tip>
The part's grain line and whether it should be cut on fold or not will be
set automatically when you call the [grainline](/reference/api/macros/grainline) or
[cutonfold](/reference/api/macros/cutonfold) macro.
</Tip>

View file

@ -1,5 +1,5 @@
---
title: constant
title: Constant options
---
If your option is a scalar value (like a string or a number),

View file

@ -1,5 +1,5 @@
---
title: counter
title: Counter options
---
For a given number of things, use a counter option.
@ -12,9 +12,17 @@ Your counter option should be a plain object with these properties:
- `count` : The default integer value
- `min` : The minimal integer value that's allowed
- `max` : The maximum integer value that's allowed
- `hide` <small>(optional)</small> : A method to [control the optional display of the option][hide]
[hide]: /reference/api/config/options#optionally-hide-options-by-configuring-a-hide-method
<Tip>
Like all options that are configured through an object, you can
add more properties to the options' object to implement functionality on
top of what's provided by the core library.
Refer to [extending options](/reference/api/part/config/options/extend) for
more details.
</Tip>
## Example

View file

@ -1,5 +1,5 @@
---
title: degrees
title: Degree options
---
For angles, use a degree option.
@ -11,9 +11,17 @@ Your degree option should be a plain object with these properties:
- `deg` : The default value in degrees
- `min` : The minimul that's allowed
- `max` : The maximum that's allowed
- `hide` <small>(optional)</small> : A method to [control the optional display of the option][hide]
[hide]: /reference/api/config/options#optionally-hide-options-by-configuring-a-hide-method
<Tip>
Like all options that are configured through an object, you can
add more properties to the options' object to implement functionality on
top of what's provided by the core library.
Refer to [extending options](/reference/api/part/config/options/extend) for
more details.
</Tip>
## Example

View file

@ -41,8 +41,7 @@ These are the types of options supported by the FreeSewing core library:
4. [**degree** options][deg] are for degrees
5. [**list** options][list] are for a list of possible choices
6. [**millimeter** options][mm] are supported but not recommended (see warning below)
7. [**percentage** options][pct] are for percentages
8. [**snapped percentage** options][snapped] constrain percentage options to (a set of) possible values
7. [**percentage** options][pct] are for percentages (and can optionally be [**snapped percentage** options][snapped])
<Tip>
@ -58,7 +57,7 @@ we do not allow them in designs contributed to FreeSewing.org
as they are a _red flag_ for poor parametric design.
If you believe you need `mm` options, look into [snapped
percentage options](snapped) instead.
percentage options][snapped] instead.
</Warning>

View file

@ -7,3 +7,90 @@ title: Extending options
Explain extending options here
</Fixme>
## Suppress translation
In the example above, you want the different `list` options to be translated.
But sometimes, there is no need for that, like in this example from Breanna:
```js
options: {
primaryBustDart: {
list: [
'06:00',
'07:00',
'08:00',
'09:00',
'10:00',
'11:00',
'11:30',
'12:00',
'12:30',
'13:00',
'13:30',
'14:00',
'15:00',
'16:00',
'17:00',
],
dflt: '06:00',
doNotTranslate: true,
},
// More here
}
```
As you can see above, you can set the `doNotTranslate` property to `true` and to indicate this.
<Note>
##### This is not a core feature
To be clear, setting this here does not do anything in core. It's merely extra
metadata you can add on the option to facilitate frontend integration.
</Note>
## Suppress translation
In the example above, you want the different `list` options to be translated.
But sometimes, there is no need for that, like in this example from Breanna:
```js
options: {
primaryBustDart: {
list: [
'06:00',
'07:00',
'08:00',
'09:00',
'10:00',
'11:00',
'11:30',
'12:00',
'12:30',
'13:00',
'13:30',
'14:00',
'15:00',
'16:00',
'17:00',
],
dflt: '06:00',
doNotTranslate: true,
},
// More here
}
```
As you can see above, you can set the `doNotTranslate` property to `true` and to indicate this.
<Note>
##### This is not a core feature
To be clear, setting this here does not do anything in core. It's merely extra
metadata you can add on the option to facilitate frontend integration.
</Note>

View file

@ -1,5 +1,5 @@
---
title: list
title: List options
---
Use a list option when you want to offer an array of choices.
@ -10,9 +10,17 @@ Your list option should be a plain object with these properties:
- `dflt` : The default for this option
- `list` : An array of available values options
- `hide` <small>(optional)</small> : A method to [control the optional display of the option][hide]
[hide]: /reference/api/config/options#optionally-hide-options-by-configuring-a-hide-method
<Tip>
Like all options that are configured through an object, you can
add more properties to the options' object to implement functionality on
top of what's provided by the core library.
Refer to [extending options](/reference/api/part/config/options/extend) for
more details.
</Tip>
## Example
@ -32,45 +40,3 @@ options: {
}
```
## Suppress translation
In the example above, you want the different `list` options to be translated.
But sometimes, there is no need for that, like in this example from Breanna:
```js
options: {
primaryBustDart: {
list: [
'06:00',
'07:00',
'08:00',
'09:00',
'10:00',
'11:00',
'11:30',
'12:00',
'12:30',
'13:00',
'13:30',
'14:00',
'15:00',
'16:00',
'17:00',
],
dflt: '06:00',
doNotTranslate: true,
},
// More here
}
```
As you can see above, you can set the `doNotTranslate` property to `true` and to indicate this.
<Note>
##### This is not a core feature
To be clear, setting this here does not do anything in core. It's merely extra
metadata you can add on the option to facilitate frontend integration.
</Note>

View file

@ -1,5 +1,5 @@
---
title: millimeter
title: Millimeter options
---
While FreeSewing supports millimeter options, we recommend
@ -13,9 +13,6 @@ A millimeter option should be a plain object with these properties:
- `mm` : The default value in millimeter
- `min` : The minimul that's allowed
- `max` : The maximum that's allowed
- `hide` <small>(optional)</small> : A method to [control the optional display of the option][hide]
[hide]: /reference/api/config/options#optionally-hide-options-by-configuring-a-hide-method
## Example
@ -49,4 +46,4 @@ percentage option][1] instead.
</Comment>
[1]: /reference/api/config/options/pct
[1]: /reference/api/part/config/options/pct

View file

@ -1,10 +1,10 @@
---
title: percentage
title: Percentage options
---
Percentage options are the bread and butter of freesewing.
Almost all your options will most likely be percentage options as
they ensure that your pattern will scale regardless of size.
they ensure that your part will scale regardless of size.
## Structure
@ -13,18 +13,6 @@ Your percentage option should be a plain object with these properties:
- `pct` : The default percentage
- `min` : The minimum percentage that's allowed
- `max` : The maximum percentage that's allowed
- `hide` <small>(optional)</small> : A method to [control the optional display of the option][hide]
- `fromAbs` <small>(optional)</small> : A method to [determine the percentage based on a value in millimeter][fromabs]
- `toAbs` <small>(optional)</small> : A method to [return the option value in millimeter][toabs]
- `snap` <small>(optional)</small> : The configuration to control [snapping of percentage options][snap]
[hide]: /reference/api/config/options#optionally-hide-options-by-configuring-a-hide-method
[fromabs]: /reference/api/config/options/pct/fromabs
[toabs]: /reference/api/config/options/pct/toabs
[snap]: /reference/api/config/options/pct/snap
<Note>
@ -33,7 +21,7 @@ Your percentage option should be a plain object with these properties:
You specify percentages in your config file. For example, `50` means 50%.
When your configuration is loaded, those percentages will be divided by 100.
So a percentage of `50` in your config file will be `0.5` when you read out that option in your pattern.
So a percentage of `50` in your config file will be `0.5` when you read out that option in your part.
###### Percentage options are not limited to the range 0-100
@ -42,6 +30,17 @@ A percentage option that spans from `-25%` to `135%` is just as valid.
</Note>
<Tip>
Like all options that are configured through an object, you can
add more properties to the options' object to implement functionality on
top of what's provided by the core library.
Refer to [extending options](/reference/api/part/config/options/extend) for
more details.
</Tip>
## Example
Below is a simple example:
@ -58,6 +57,17 @@ options: {
## Advanced use
Percentage options have a few more tricks up their sleeve:
Percentage options have more advanced features that are supported by the core library.
You can unlock those features by adding the following properties to your option:
- `fromAbs`: A method to [determine the percentage based on a value in millimeter][fromabs]
- `toAbs`: A method to [return the option value in millimeter][toabs]
- `snap`: The configuration to control [snapping of percentage options][snap]
[fromabs]: /reference/api/config/options/pct/fromabs
[toabs]: /reference/api/config/options/pct/toabs
[snap]: /reference/api/config/options/pct/snap
Refer to the relevant documentation for more details:
<ReadMore />

View file

@ -15,7 +15,7 @@ value.
<Note>
Note that this method will not change the percentage of the option.
It will merely return return a percentage value. It is up to the
It will merely return a percentage value. It is up to the
frontend designer to then either set this value, or suggest it to
the user.
@ -27,16 +27,15 @@ The `fromAbs` property should hold a function with the following
signature:
```js
function toAbs(millimeter, settings) {
function fromAbs(millimeter, settings) {
// return a percentage here (0.5 is 50%)
}
```
The first parameter is the desired value in millimeter (for example
`130` for `13cm`).
The second parameter is the pattern's run-time configuration
or [settings](/reference/api/settings) which holds -- among other things -- the
measurements provided by the user.
The second parameter is the pattern's [settings](/reference/api/settings) object
which holds -- among other things -- the measurements provided by the user.
## Example
@ -74,17 +73,14 @@ that will do the work for you:
// First import the method
import { pctBasedOn } from '@freesewing/core'
const config = {
// ...
options: {
chestEase: {
pct: 8,
min: 0,
max: 20,
// Pass the measurement name as parameter
// and spread the return value into your option
...pctBasedOn('chest')
}
options: {
chestEase: {
pct: 8,
min: 0,
max: 20,
// Pass the measurement name as parameter
// and spread the return value into your option
...pctBasedOn('chest')
}
}
```
@ -93,5 +89,6 @@ This will not only add an `fromAbs()` method to your option --
one that will return the percentage of any millimeter value passed into it --
it will also add a `toAbs()` method that does the inverse: return the
value in millimeter of whatever percentage the option is set to.
See [Reporting a percentage option value in
millimeter](/reference/api/config/options/pct/toabs) for details.

View file

@ -15,14 +15,24 @@ Your snapped percentage option should be a plain object with these properties:
- `pct` : The default percentage
- `min` : The minimum percentage that's allowed
- `max` : The maximum percentage that's allowed
- `snap`: Holds the snap configuration (see [Snap configuration](#))
- `snap`: Holds the snap configuration (see below)
- `toAbs`: a method returning the **millimeter value** of the option ([see `toAbs()`][toabs])
- `hide` <small>(optional)</small> : A method to [control the optional display of the option][hide]
<Tip>
##### Values for snapped percentage options are available through `absoluteOptions`
Your draft method can not only destructure the `options` property to get access to options,
it can also desctructure the `absoluteOptions` property to get access to the values
for those options with snaps configured.
See [the part `draft()` method](/reference/api/part/draft) for mor details.
</Tip>
## Snap configuration
A snapped percentage option requires a `snap` property that will determine
what values to snap to.
what **value in millimeter** to snap to.
There are three different scenarios:
@ -32,13 +42,13 @@ When `snap` holds a number, the option will be _snapped_ to a
multiple of this value.
In the example below, the absolute value of this option will be set to a multiple of `7`
(so one of `7`, `14`, `21`, `28`, `35`, ...).
(so one of `0mm`, `7mm`, `14mm`, `21mm`, `28mm`, `35mm`, `42mm`, ...).
```js
myOption: {
pct:5,
min: 0
max: 35,
max: 25,
snap: 7,
toAbs: (pct, { measurements }) => measurements.waistToFloor * pct
}
@ -58,7 +68,7 @@ When snap holds an array of numbers, the option will be _snapped_ to one of
the numbers unless it's further away than half the distance to its closest neighbor.
In the example below, if the absolute value returned by `toAbs()` is in the
region of influence -- in this example between 4.5 and 69.5 -- the nearest snap value
region of influence -- in this example between `4.5mm` and `69.5mm` -- the nearest snap value
will be used. If instead it is outside the region of influence, the result of
`toAbs()` will be uses as-is.
@ -74,19 +84,20 @@ myOption: {
### snap is a plain object with `metric` and `imperial` properties that each hold an array of numbers
In this case, the behavior is exaxtle the same as when `snap` holds an array
In this case, the behavior is similar to when `snap` holds an array
of numbers.
The differnce is that this allows you to supply a different list of snap values
The difference is that this allows you to supply a different list of snap values
for users using metric or imperial units.
In the example below, the value of [settings.units](/api/settings/units) will
determine which list of snap values gets used.
Then, if the absolute value returned by `toAbs()` is in the
region of influence -- in this example between 4.5 and 69.5 -- the nearest snap value
region of influence -- in this example between `4.5mm` and `69.5mm` for metric
and between `12.7mm` and `88.9mm` for imperial -- the nearest snap value
will be used. If instead it is outside the region of influence, the result of
`toAbs()` will be uses as-is.
`toAbs()` will be used as-is.
```js
myOption: {
@ -95,7 +106,7 @@ myOption: {
max: 35,
snap: {
metric: [7, 12, 21, 34, 53, 64 ],
imperial: [25.4, 50.8, 76.3 ],
imperial: [25.4, 50.8, 76.2 ],
}
}
```
@ -127,10 +138,10 @@ We have a few different ways we can approach this:
We use a percentage option based on a vertical measurement, like
`waistToFloor`.
The elastic width people end up with is something like 34.12mm for
user A and 27.83mm for user B.
The elastic width people end up with is something like `34.12mm` for
user A and `27.83mm` for user B.
Those are not widths for sale in the store, so that's not great.
Elastic of that width is not for sale in the store, so that's not great.
### Approach B: We use a list option
@ -154,23 +165,22 @@ with:
- Our list of standard elastic widths as _snaps_
For typical humans, our options will _snap_ to the closest match in our
list and behave just like Approach A (with a list option).
list and behave just like Approach B (with a list option).
For dolls and giants, the option will revert to the parametric value and
behave just like Approach B (with a percentage option).
Sweet!
behave just like Approach A (with a percentage option).
## How snapped percentage options work
Before we wade into the details, let's first agree on terminology:
Before we wade into the details of how snapped percentage options are handled
under the hood, let's first agree on terminology:
- The **percentage value** is the page passed by the user for the option.
Its value always represents a percentage.
- The **percentage value** is the value passed by the user for the option.
Its value always represents a percentage. For example `0.5` for 50%.
- The **millimeter value** is the result of feeding the **percentage value** to
the `toAbs()` method. Its value always represents millimeters.
the `toAbs()` method. Its value always represents millimeters. For example `12mm`.
- The **snap values** are the values provided by the snap confguration.
Each of the values always represents millimeters.
Each of the values always represents millimeters (even for imperial users).
Under the hood, and snapped percentage option will:
@ -207,38 +217,8 @@ This system results in the best of both worlds:
- When the input measurements go somewhere the designer did not anticipate,
the option will just behave as a regular percentage option
## Using snapped percentage options in your pattern code
[toabs]: /reference/api/part/config/options/pct/toabs
This is all well and good, but how do you use this?
[pct]: /reference/api/part/config/options/pct
Well, just like you can get the `options` object from our shorthand call,
you can now get the `absoluteOptions` object that holds absolute values
for those options with snaps configured.
In our paco example, what used to be:
```js
store.set('ankleElastic', measurements.waistToFloor * options.ankleElastic)
```
is now:
```js
store.set('ankleElastic', absoluteOptions.ankleElastic)
```
<Note>
There's really no added value in setting this in the store as `absoluteOptions`
is available everywhere, but we've changed as little as possible in the example
to clarify the difference.
</Note>
[toabs]: /reference/api/config/options/pct/toabs
[pct]: /reference/api/config/options/pct
[list]: /reference/api/config/options/list
[hide]: /reference/api/config/options#optionally-hide-options-by-configuring-a-hide-method
[list]: /reference/api/part/config/options/list

View file

@ -24,9 +24,8 @@ function toAbs(percentage, settings) {
The first parameter is the percentage value provided by the user (for example
`0.5` for `50%`).
The second parameter is the pattern's run-time configuration
or [settings](/reference/api/settings) which holds -- among other things -- the
measurements provided by the user.
The second parameter holds the pattern's [settings](/reference/api/settings) object
which holds -- among other things -- the measurements provided by the user.
## Example
@ -64,17 +63,14 @@ that will do the work for you:
// First import the method
import { pctBasedOn } from '@freesewing/core'
const config = {
// ...
options: {
chestEase: {
pct: 8,
min: 0,
max: 20,
// Pass the measurement name as parameter
// and spread the return value into your option
...pctBasedOn('chest')
}
options: {
chestEase: {
pct: 8,
min: 0,
max: 20,
// Pass the measurement name as parameter
// and spread the return value into your option
...pctBasedOn('chest')
}
}
```
@ -82,5 +78,7 @@ const config = {
This will not only add an `toAbs()` method to your option -- one that will return
the value in millimeter of whatever percentage the option is set to -- it will
also add a `fromAbs()` method that does the inverse: return the percentage of
any millimeter value passed into it. See [Setting a value in millimeter as a
any millimeter value passed into it.
See [Setting a value in millimeter as a
percentage option](/api/config/options/pct/fromabs) for details.

View file

@ -1,229 +1,46 @@
---
title: "Parts: The `draft()` method"
title: "The part's draft method"
---
A `Part` in FreeSewing holds all data, logic, and configuration of a Design.
Parts truly are the building blocks of FreeSewing as they not only provide
the configurarion, but also a `draft()` method that does the actual work
of drafting a parametric design.
## Part structure
A part is an object with the following properties:
| Property | Description |
| -------- | ----------- |
| `draft` | The method that will draft the part (__required__) |
| `measurements` | An array of required measurements |
| `optionalMeasurements` | An array of optional measurements |
| `options` | An object of options |
| `plugins` | A plugin or array of plugins |
## A part's `draft()` method
Each part **must** have a `draft` property that holds a method that will draft the part.
The method's signature is as follows:
In other words, this method is where the actual work happens. The method's signature
is as follows:
```js
function draft(props)
```
The method received a single parameter, an object which you can _destructure_ to
The draft method receives a single parameter, an object which you can _destructure_ to
access the following properties:
- [Content constructors](#content-constructors)
- `Path`
- `Point`
- `Snippet`
- [Content containers](#content-constainers)
- `paths`
- `points`
- `snippets`
- [The `macro` runner](#the-macro-runner)
- [Access to settings](#access-to-settings)
- `absoluteOptions`
- `complete`
- `measurements`
- `options`
- `paperless`
- `sa`
- `scale`
- [Top-level methods](#access-to-settings)
- `units()`
- `hide()`
- `unhide()`
- [Utilities](#utilities)
- [Logging via the `log` object](#logging-via-the-log-object)
- [The `store`](#the-store)
- [The `part` object which you must return](#the-part-object-which-you-must-return)
### Content constructors
There are three things you can add to a part: points, paths and snippets.
For each of those, you receive the relevant constructor:
| Property | Description |
| --------:| ----------- |
| `Path` | A [Path constructor](/reference/api/path) to create new paths |
| `Point` | A [Point constructor](/reference/api/point) to create new points |
| `Snippet` | A [Snippet constructor](/reference/api/snippet) to create new snippets |
| --------:|:----------- |
|| **_Content constructors_** |
| `Path` | A [Path constructor](/reference/api/path) to create new paths |
| `Point` | A [Point constructor](/reference/api/point) to create new points |
| `Snippet` | A [Snippet constructor](/reference/api/snippet) to create new snippets |
|| **_Content containers_** |
| `paths` | Add a Path to your part by adding it to this object |
| `points` | Add a Points to your part by adding it to this object |
| `snippets` | Add a Snippet to your part by adding it to this object |
|| **_Access to settings_** |
| `absoluteOptions` | Access to `settings.absoluteOptions` |
| `complete` | Access to `settings.complete` |
| `measurements` | Access to `settings.measurements` |
| `options` | Access to `settings.options` |
| `paperless` | Access to `settings.paperless` |
| `sa` | Access to `settings.sa` |
| `scale` | Access to `settings.scale` |
|| **_Access to utilities_** |
| `getId` | See [the getId documentation](/refence/api/part/draft/getid) |
| `hide` | See [the hide documentation](/refence/api/part/draft/hide) |
| `log` | See [the logging documentation](referenec/api/store/logs) |
| `macro` | See [the macros documentation](/reference/macros/) |
| `setHidden` | See [the setHidden documentation](/refence/api/part/draft/sethidden) |
| `store` | See [the store documentation](/reference/api/store) |
| `unhide` | See [the unhide documentation](/refence/api/part/draft/unhide) |
| `units` | See [the units documentation](/refence/api/part/draft/units) |
| `utils` | See [the utils documentation](/reference/api/utils) |
|| **_Return value_** |
| `part` | Your draft method **must** return this |
for example:
```js
new Point(19, 80)
```
### Content containers
Creating a Point, Path, or Snippet by itself doesn't do much.
To add them to your part, assign them to the relevant container object:
| Property | Description |
| --------:| ----------- |
| `paths` | Add a Path to your part by storing it in this container object |
| `points` | The part's points container |
| `snippets` | The part's snippets container |
for example:
```js
points.example = new Point(19, 80)
```
### The `macro` runner
| Property | Description |
| --------:| ----------- |
| `macro` | The macro runner. See [the macros documentation](/reference/macros/) |
for example:
```js
points.title = new Point(100,100)
macro('title', {
at: points.title,
nr: 1,
title: 'front'
})
```
### Access to settings
The (relevant entries of the) `settings` object as by the user are also available:
| Property | Description |
| --------:| ----------- |
| `absoluteOptions` | FIXME |
| `complete` | Access to `settings.complete` |
| `measurements` | Access to `settings.measurements` |
| `options` | Access to `settings.options` |
| `paperless` | Access to `settings.paperless` |
| `sa` | Access to `settings.sa` |
| `scale` | Access to `settings.scale` |
for example:
```js
points.example = new Point(19, measurements.head)
```
### Top-level methods
There's a couple of top-level methods that you can use:
| Property | Description |
| --------:| ----------- |
| `units` | An instance of `utils.units` preconfigured with `settings.units` |
| `hide` | Call `hide()` to hide the part |
| `unhide` | Call `unhide()` to unhide/reveal the part |
for example:
```js
console.log(`123mm is ${units(123)}`)
hide()
```
### Utilities
| Property | Description |
| --------:| ----------- |
| `utils` | A [Utils](/reference/api/utils) instance with utility methods |
for example:
```
points.example = new Point(
measurements.head * utils.stretchToScale(options.stretch),
0
)
```
### Logging via the `log` object
| Property | Description |
| --------:| ----------- |
| `log` | The default logging object from the store (FIXME) |
The `log` object has methods attached to it with the following signature:
```js
function loglevel(string msg)
```
The different log levels are: `debug`, `info`, `warning`, and `error`.
For example:
```js
log.info('Hello')
```
### The store
| Property | Description |
| --------:| ----------- |
| `store` | Holds the [Store](/reference/api/store) instance that is shared across parts |
The store is how you can share data between parts. For example:
```js
store.set('example', 12)
// In some other part
let value = store.get('example') // (value now holds 12)
```
### The `part` object which you must return
| Property | Description |
| --------:| ----------- |
| `part` | The part container itself. **You must return this** |
Last but not least, there is the `part` object which you must return:
```js
// Do clever things here
return part
```
## A part's `measurements` list
The `measurements` property should hold a list (an array) of all the measurements that are required for your part.
For example:
```js
const part = {
draft: ({ part }) => part, // Obviously this is silly
measurements: [ 'head', 'chest', 'waist' ]
}
```
<Note>
You only need to include the measurements required for this part. Not the measurements for any dependencies.
## A part's `optionalMeasurements` list
## A part's `options` list
## A part's `plugin` list

View file

@ -0,0 +1,31 @@
---
title: getId()
---
Calling `getId()` in a part's draft method will return an integer the can be used as an
for ID Points/Paths/Snippets. This method will ensure the ID is unique by
keeping an internal incremental counter of the IDs that have been used.
It is typically used when programatically adding points, paths, or snippets.
## getId() signature
```js
int|string getId(prefix='')
```
This methiod takes an optional parameter that will be used as a prefix for the ID.
## getId() example
```js
cont part = {
name: 'examples.getid',
draft: ({ Point, points, getId, part }) => {
for (let i=0;i<10;i++) {
points[getId()] = new Point(i*10, i*10)
}
return part
}
}
```

View file

@ -0,0 +1,24 @@
---
title: hide()
---
Calling `hide()` in a part's draft method will mark the part as hidden.
<Tip>This method returns the `part` object, so it's chainable</Tip>
<Related>
The [unhide](/reference/api/part/draft/unhide) and
[setHidden](/reference/api/part/draft/sethidden) methods also control a
part's visibility
</Related>
## hide() example
```js
cont part = {
name: 'examples.hide',
draft: ({ hide, part }) => part.hide()
}
```

View file

@ -0,0 +1,28 @@
---
title: setHidden()
---
Calling `setHidden()` in a part's draft method will mark the part either hidden
or not, depending on whether you:
- Pass a *truthy* value: part will be hidden
- Pass a *falsy* value: part will be unhidden/revealed
<Tip>This method returns the `part` object, so it's chainable</Tip>
<Related>
The [hide](/reference/api/part/draft/hide) and
[unhide](/reference/api/part/draft/unhide) also control a
part's visibility
</Related>
## setHidden() example
```js
cont part = {
name: 'examples.hide',
draft: ({ setHidden, part }) => part.setHidden(true)
}
```

View file

@ -0,0 +1,24 @@
---
title: unhide()
---
Calling `unhide()` in a part's draft method will mark the part as not hidden.
<Tip>This method returns the `part` object, so it's chainable</Tip>
<Related>
The [hide](/reference/api/part/draft/hide) and
[setHidden](/reference/api/part/draft/sethidden) methods also control a
part's visibility
</Related>
## unhide() example
```js
cont part = {
name: 'examples.hide',
draft: ({ unhide, part }) => part.unhide()
}
```

View file

@ -0,0 +1,22 @@
---
title: units()
---
Calling `units()` in a part's draft method will format a float you pass it --
which should represent a value in mm -- into the units requested by the user.
The returned value is to be used in presentation only, as it will be
a string that includes the user's units.
## units() example
```js
cont part = {
name: 'examples.units',
draft: ({ log, measurements, part }) => {
log.info(`Pattern drafted for a ${units(measurements.chest)} chest`)
return part
}
}
```

View file

@ -1,32 +0,0 @@
---
title: Part.getId()
---
A part's `getId()` method will return an integer the can be used as an
for ID Points/Paths/Snippets. This method will ensure the ID is unique by
keeping an internal incremental counter of the IDs that have been used.
It is typically used when programatically adding points, paths, or snippets.
## Part.getId() signature
```js
int part.getId(prefix='')
```
This methiod takes an optional parameter that will be used as a prefix for the ID.
## Part.getId() example
```js
export default function (part) {
const { Point, points } = part.shorthand()
for (let i=0;i<10;i++) {
const id= part.getId()
points[id] = new Point(i*10, i*10)
}
// You would do more useful stuff before returning
return part
}
```

View file

@ -1,37 +0,0 @@
---
title: Part.raise.debug()
---
A part's `raise.debug()` method will log a debug-level event.
Debug events are typically used to pass information to pattern developers
so that can troubleshoot issues with the pattern.
What happens with this data is entirely up to the frontend developer.
As such, data can by anything you like. A string is common, but you
can also add arrays or objects with data or information you want to
use in your frontend.
<Tip>
All raise methods are available via [the shorthand method](/reference/api/part/shorthand)
</Tip>
## Part.raise.debug() signature
```js
raise.debug(data)
```
## Part.raise.debug() example
```js
export default function (part) {
const { raise } = part.shorthand()
raise.debug('Entered the draft method of partmyPart')
// You would do more useful stuff before returning
return part
}
```

View file

@ -1,64 +0,0 @@
---
title: Part raise methods
---
A part's different `raise` methods are used to bring information to the attention
of the user, or developer. You can think of them as logging methods the register
data.
<Warning>
##### FreeSewing v3 breaking changes
This behavior is likely to change in FreeSewing v3. Refer to [the
roadmap](https://github.com/freesewing/freesewing/discussions/1278) for details.
</Warning>
There are four different types of information with their own method:
<ReadMore list />
Practically, the pattern object has an `events` property as such:
```js
events: {
debug: [],
error: [],
info: [],
warning: []
}
```
Calling the relevant `raise` method will add the data you pass to it to the relevant array.
For example, if we use:
```js
raise.info('Hello')
```
The result will be:
```js
events: {
debug: [],
error: [],
info: [
'Hello'
],
warning: []
}
```
<Note>
##### Errors are not harmless, the rest is
It's important to note that only the `error` type has an impact.
The other types merely add information to the pattern.
But if an error is raised, core won't attempt to pack the pattern parts on the page.
In other words, it will abort after the draft, and not provide a layout.
</Note>

View file

@ -1,34 +0,0 @@
---
title: Part.raise.error()
---
A part's `raise.error()` method will log a error-level event.
Unlike other raised events which have no side-effects, if there is one or more
events of type `error`, the pattern will not be completed.
In other words, you should only use this when end up in a situation
you cannot recover from. If not, [raise a warning](/reference/api/part/raise/warning).
<Tip>
All raise methods are available via [the shorthand method](/reference/api/part/shorthand)
</Tip>
## Part.raise.error() signature
```js
raise.error(data)
```
## Part.raise.error() example
```js
export default function (part) {
const { raise, measurements } = part.shorthand()
if (measurements.hips > measurements.chest) {
raise.warning('Chest circumference smaller than hip circumference is currently unsupported. Aborting.')
return part
}
}
```

View file

@ -1,37 +0,0 @@
---
title: Part.raise.info()
---
A part's `raise.info()` method will log a ingo-level event.
Info events are typically used to pass information to users
that is informative to them.
What happens with this data is entirely up to the frontend developer.
As such, data can by anything you like. A string is common, but you
can also add arrays or objects with data or information you want to
use in your frontend.
<Tip>
All raise methods are available via [the shorthand method](/reference/api/part/shorthand)
</Tip>
## Part.raise.info() signature
```js
raise.info(data)
```
## Part.raise.info() example
```js
export default function (part) {
const { raise, options } = part.shorthand()
if (options.shortSleeves) {
raise.info('Not drafting french cuffs because you opted for short sleeves')
return part
}
}
```

View file

@ -1,43 +0,0 @@
---
title: Part.raise.warning()
---
A part's `raise.warning()` method will log a warning-level event.
Warning events are typically used to pass information to pattern developers
so that can troubleshoot issues with the pattern, or users to warn them
that something is sub-optimal.
What happens with this data is entirely up to the frontend developer.
As such, data can by anything you like. A string is common, but you
can also add arrays or objects with data or information you want to
use in your frontend.
<Tip>
All raise methods are available via [the shorthand method](/reference/api/part/shorthand)
</Tip>
## Part.raise.warning() signature
```js
raise.warning(data)
```
## Part.raise.warning() example
```js
export default function (part) {
const { raise, measurements } = part.shorthand()
if (measurements.hips > measurements.chest) {
raise.warning(`
Chest circumference is smaller than hip circumference.
This might lead to unexpected results
`)
}
// You would do more useful stuff before returning
return part
}
```

View file

@ -1,58 +0,0 @@
---
title: Part.removeCut()
---
A part's `removeCut()` method allows designers to remove cutting information
that was added through [Part.addCut()](/reference/api/part/addcut).
## Part.addCut() signature when adding cut information
```js
Part.part.addCut(cut=2, material='fabric', identical=false)
```
In this form, this methiod takes three parameters:
| Parameter | type | description | default |
| --------- | ---- | ----------- | ------- |
| `cut` | integer | The amount of times this part should be cut. | `2` |
| `material` | string | The name of the material, typically one of `fabric`, `lining`, `facing`, `interfacing`, `canvas`, or `various` | `fabric` |
| `identical` | boolean | Whether or not parts should be cut identical (true) or mirrored (false). Mirorred is often referred to as _good sides together_ | `false` |
## Part.addCut() signature when removing cut information
```js
Part.part.addCut(false, material='fabric')
```
In this form, this methiod takes two parameters:
| Parameter | type | description | default |
| --------- | ---- | ----------- | ------- |
| `cut` | `boolean` | Pass `false` to remove the cut info for the material passed as the second parameter | `2` |
| `material` | string | The name of the material, typically one of `fabric`, `lining`, `facing`, `interfacing`, `canvas`, or `various` | `fabric` |
## Part.addCut() example
```js
export default function (part) {
// Cut two from fabric with good sides together
part.addCut(2, 'fabric')
// Cut seven from lining, identical
part.addCut(7, 'lining')
// Remove the lining cut info (but keep the fabric info)
part.addCut(false, 'lining')
// You would do more useful stuff before returning
return part
}
```
<Tip>
The part's grain line and whether it should be cut on fold or not will be
set automatically when you call the [grainline](/reference/api/macros/grainline) or
[cutonfold](/reference/api/macros/cutonfold) macro.
</Tip>

View file

@ -1,86 +0,0 @@
---
title: Part.shorthand()
---
A part's `shorthand()` method provides easy access to a number of
internal objects and properties. It does so be returning an object
that contains all you need to draft your pattern parts. It is
typically combined with object destructuring to pull out those
properties you need.
As the name implies, this method can save you a bunch of typing, and keep your
code concise. We highly recommend you use it.
## Part.shorthand() signature
```js
object Part.shorthand();
```
The `Part.shorthand()` method returns a plain object with the following properties:
| Property | Description |
| --------:| ----------- |
| `config` | The pattern configuration |
| `complete` | Holds `pattern.settings.complete` |
| `events` | An object holding the raised events (see [Part.raise](/reference/api/part/raise/)) |
| `final` | `true` is this is a full draft, or `false` if this is a sample. |
| `macro` | The macro runner. See [the macros documentation](/reference/macros/) |
| `measurements` | Holds `pattern.settings.measurements` |
| `paperless` | Holds `pattern.settings.paperless` |
| `Path` | The [Path constructor](/reference/api/path) |
| `paths` | Holds `part.paths` |
| `Point` | The [Point constructor](/reference/api/point) |
| `points` | Holds `part.points` |
| `scale` | Holds `pattern.settings.scale` |
| `Snippet` | The [Snippet constructor](/reference/api/snippet) |
| `snippets` | Holds `part.snippets` |
| `options` | Holds `pattern.settings.options` |
| `raise` | Holds [Part.raise](/reference/api/part/raise/) thus giving you access to the various raise methods |
| `sa` | Holds `pattern.settings.sa` |
| `store` | Holds `pattern.store`, a [Store](/reference/api/store) instance that is shared across parts |
| `utils` | A [Utils](/reference/api/utils) instance with utility methods |
| `units` | A context-aware version of `utils.units` |
## Part.shorthand() example
```js
// You could write this:
part.points.from = new part.Point(
pattern.measurements.chest / 2,
pattern.options.armholeDepth
)
part.points.to = new part.Point(
part.points.from.x + pattern.settings.sa,
part.points.from.y
)
part.paths.example = new part.Path()
.move(parts.points.from)
.line(parts.points.to)
// Or use shorthand:
const { Point, points, measurements, options, sa } = part.shorthand()
points.from = new Point(
measurements.chest / 2,
options.armholeDepth
)
points.to = new part.Point(
points.from.x + sa,
points.from.y
)
paths.example = new Path()
.move(points.from)
.line(points.to)
```
<Tip>
As you can see in the example above, you can/should load only
the shorthand you need by using object destructuring.
</Tip>

View file

@ -1,36 +0,0 @@
---
title: Part.units()
---
A part's `units()` method will formats a float you pass it, which should
represent a value in mm, into the units requested by the user.
The returned value is to be used in presentation only, as it will be
a string that includes the user's units.
<Tip>
###### This method is available as shorthand
You can access this units method from the [Part.shorthand](/reference/api/part/shorthand) method:
```js
let { units } = part.shorthand();
```
</Tip>
## Part.units() signature
```js
string part.units(float number)
```
## Part.units() example
```js
export default function (part) {
const { raise, units, measurements } = part.shorthand()
raise.info(`Pattern drafted for a ${units(measurements.chest)} chest`)
}
```