Web Development

How To Write A Product Roadmap That Works


Product roadmaps help you visualize how your product will develop over time. But product roadmaps also present challenges—it can be difficult to build one that is realistic and responds to your user’s needs. Learn how to rethink the product roadmap to...

ASP.NET Core Updates In .NET 6 Release Candidate 1

.NET 6 Release Candidate 1 (RC1) is now available and includes many great new improvements to ASP.NET Core.

Here’s what’s new in this preview release:
Render Blazor components from JavaScript

Blazor custom elements

Manipulate the query string from Blazor

.NET to JavaScript streaming

PageX and PageY in MouseEventArgs

Blazor templates updated to set page titles

Disabled long-polling transport for Blazor Server

Collocate JavaScript files with pages,
The post ASP.NET Core updates in .NET 6 Release Candidate 1 appeared first on ASP.NET Blog.

Announcing .NET 6 Release Candidate 1

We are happy to release .NET 6 Release Candidate 1. It is the first of two “go live” release candidate releases that are supported in production. For the last month or so, the team has been focused exclusively on quality improvements that resolve functional or performance issues in new features or regressions in existing ones.
The post Announcing .NET 6 Release Candidate 1 appeared first on .NET Blog.

.NET September 2021 Updates – 5.0.10 And 3.1.19

Today, we are releasing the .NET September 2021 Updates. These updates contains reliability and other improvements. See the individual release notes for details on updated packages.

You can download 5.0.10 and 3.1.19 versions for Windows, macOS, and Linux, for x86, x64,
The post .NET September 2021 Updates – 5.0.10 and 3.1.19 appeared first on .NET Blog.

Update On .NET Multi-platform App UI (.NET MAUI)

The .NET 6 project started in late 2020 as we were finishing .NET 5 where we started the journey to unify the .NET platform runtimes, libraries, and SDK. .NET 5 proved to be a very successful release, the first of the annual November releases,
The post Update on .NET Multi-platform App UI (.NET MAUI) appeared first on .NET Blog.

Static Analysis Fixes In Visual Studio 2019 Version 16.11

The C++ static analysis team is committed to making your C++ coding experience as safe as possible. We are adding richer code safety checks and addressing high impact customer feedback bugs posted on the C++ Developer Community page. Thank you for engaging with us and giving us great feedback on the past releases and early previews leading to this point. 
The post Static Analysis Fixes in Visual Studio 2019 version 16.11 appeared first on C++ Team Blog.

Envoyer: Transfer Projects


Starting today, it's possible for project owners to transfer projects to another Envoyer account. Collaborators will not be able to transfer a project away from its owner.Project transfers may be initiated from the project's settings p...

Taking The EF Core Azure Cosmos DB Provider For A Test Drive

The release of EF Core 6.0 is right on the horizon (as I write this). The team has been hard at work adding features. One area of focus is the Azure Cosmos DB experience. We received feedback that many developers would prefer to use the provider for Cosmos DB but are waiting for certain key features.
The post Taking the EF Core Azure Cosmos DB Provider for a Test Drive appeared first on .NET Blog.

Creators, It’s Time To Protect Your Independence

The creator economy, defined by creators monetizing audiences ushered in an era of independence. Creators wield massive influence, with platforms wooing them with funding, brands clamoring for partnerships, and devotees gobbling up any product they pro...

MSVC C++20 And The /std:c++20 Switch

We are excited to announce that in Visual Studio 2019 version 16.11, we have added the /std:c++20 switch to the set of language mode switches available. The addition of this switch indicates that we’ve reached a point of sufficient stabilization of the MSVC C++20 feature set for it be used in production,
The post MSVC C++20 and the /std:c++20 Switch appeared first on C++ Team Blog.

API Deprecation At Shopify: 2021-10 Edition


On October 1, 2021, the 2021-10 API version will become stable and ready for general usage, and the 2020-10 version will become unsupported. The 2020-10 API version, which will become the default version, includes breaking API changes. Learn what thos...

File IO Improvements In .NET 6

For .NET 6, we have made FileStream much faster and more reliable, thanks to an almost entire re-write. For same cases, the async implementation is now a few times faster!

We also recognized the need of having more high-performance file IO features: concurrent reads and writes,
The post File IO improvements in .NET 6 appeared first on .NET Blog.

Introducing The .NET MAUI Community Toolkit (Preview)

The Community Toolkit team is excited to announce the first pre-release two new .NET Multi-platform App UI (.NET MAUI) Toolkits:
CommunityToolkit.Maui

CommunityToolkit.Maui.Markup
As announced last month, these libraries are the evolution of the Xamarin Community Toolkits. They contain .NET MAUI Extensions,
The post Introducing the .NET MAUI Community Toolkit (Preview) appeared first on .NET Blog.

C++20 Coroutine Improvements In Visual Studio 2019 Version 16.11

This post includes contributions from Terry Mahaffey and Ramkumar Ramesh.

We last blogged about coroutine support in Visual Studio 2019 version 16.8. In the releases since 16.8 we’ve introduced several new coroutine features and improvements. This post is a round up of those improvements,
The post C++20 Coroutine Improvements in Visual Studio 2019 version 16.11 appeared first on C++ Team Blog.

Learn To Build Applications With F#

You might be completely new to .NET, or a seasoned C# / VB.NET developer who wants to expand their horizons. Either way, F# is a great language to learn.

F# makes it easy to write succinct, robust, and performant code. It has a lightweight syntax that requires very little code to build software.
The post Learn to build applications with F# appeared first on .NET Blog.

New Compiler Warnings For Dynamic Initialization And User Defined Sections

We’ve added two new warnings to MSVC for misuses of binary sections reserved for the compiler. This short post will explain the issues which they warn against, and potential fixes for your code.

The MSVC C++ compiler provides several ways to create sections and place data in them.
The post New Compiler Warnings for Dynamic Initialization and User Defined Sections appeared first on C++ Team Blog.

New .NET 6 APIs Driven By The Developer Community

.NET 6 is on the way, and I wanted to share some of my favorite new APIs in .NET and ASP.NET Core that you are going to love. Why are you going to love them? Well because they were directly driven by our fantastic .NET developer community!
The post New .NET 6 APIs driven by the developer community appeared first on .NET Blog.

Understanding The Cost Of C# Delegates

Delegates are widely used in C# (and .NET, in general). Either as event handlers, callbacks, or as logic to be used by other code (as in LINQ).

Despite their wide usage, it’s not always obvious to the developer what delegate instantiation will look like.
The post Understanding the cost of C# delegates appeared first on .NET Blog.

10 Myths About Prototyping, Busted


Prototyping is an essential part of the design process, allowing for rapid feedback and user insights. Unfortunately, common myths about the downsides of prototyping mean it isn't used as frequently as it should be. Learn the truth about prototyping a...

Performance Improvements In .NET 6

Four years ago, around the time .NET Core 2.0 was being released, I wrote Performance Improvements in .NET Core to highlight the quantity and quality of performance improvements finding their way into .NET. With its very positive reception, I did so again a year later with Performance Improvements in .NET Core 2.1,
The post Performance Improvements in .NET 6 appeared first on .NET Blog.

The Entrepreneur’s Guide To Small Business Finance


Funding is one of the most important financial choices you’ll make in your business. Learn about your small business financing options, plus essential small business finance skills for successful entrepreneurs, including building a budget, tracking sp...

Attach To A Remote Process With LLDB In Visual Studio 2022 Preview 3

You can now use Attach to Process to remote debug processes with GDB or LLDB in Visual Studio. The ability to attach to a process running on a remote system with GDB was added in Visual Studio 2019. The ability to attach to a process with LLDB is new in Visual Studio 2022 Preview 3.
The post Attach to a Remote Process with LLDB in Visual Studio 2022 Preview 3 appeared first on C++ Team Blog.

ASP.NET Core Updates In .NET 6 Preview 7

.NET 6 Preview 7 is now available and includes many great new improvements to ASP.NET Core.

Here’s what’s new in this preview release:
Parity with existing experiences for minimal APIs

Added IResult implementations for producing common HTTP responses

Support Request, Response and User for minimal actions

Minimal host and template improvements

Supply Blazor component parameters from the query string

Replace the current URI in the browser history from Blazor

New DynamicComponent.Instance property

Blazor streaming interop from JavaScript to .NET

Large file upload &
The post ASP.NET Core updates in .NET 6 Preview 7 appeared first on ASP.NET Blog.

ARM64EC Support In Visual Studio

ARM64EC (“Emulation Compatible”) is a new application binary interface (ABI) for building apps for Windows 11 on ARM. With ARM64EC, you can build new native apps that can run on ARM or incrementally transition existing x64 apps to native performance on ARM.
The post ARM64EC Support in Visual Studio appeared first on C++ Team Blog.

Moving A Project To C++ Named Modules

There is a lot of hype (and perhaps restraint) to using modules in projects. The general blocker tends to be build support, but even with good build support there is a distinct lack of useful resources for practices around moving projects to using named modules (not just header units).
The post Moving a project to C++ named Modules appeared first on C++ Team Blog.

Tips For An Efficient Shopify Theme Review Process


The Shopify Theme Store is now open to partners! It’s time to list your theme and establish yourself as a trusted Shopify theme developer. But first you must submit your theme for review. Success during the theme review stage actually starts well befo...

Forge: Introducing The Forge CLI


Today we're proud to introduce you to our new command-line tool: **[Forge CLI](https://github.com/laravel/forge-cli)**. This new open-source tool provides a number of helpful commands that can assist you in managing your Forge servers,...

Request For Comments: New JS API

I’m excited to officially unveil something that’s been in the works for quite a
while now: a (proposal for a) brand new JavaScript API for Sass. This API has
been redesigned from the ground up based on lessons learned from both the Node
Sass API and various other historical Sass APIs in other languages through the
years, and it addresses many of the shortcomings of the existing API.

The API has four main components, all of which I’ll cover in this post:

The core compilation API
The logger API
The importer API
The function API
As you read on, remember that this API is still just a proposal. We want to hear
from you, our users, whether it meets your needs and how we can improve it
before we lock it in to a full release. So go ahead and make your voices known
on the issue tracker!


Why a New API? permalinkWhy a New API?

The existing JavaScript API is showing its age. It predates Dart Sass, having
been originally designed for the node-sass package, which wrapped the
now-deprecated implementation. (That’s why we call it the “Node Sass
API”!) It grew organically and often messily along with LibSass, and ended up
with more than a few awkward legacy behaviors. Many of these behaviors are more
of a pain for implementation than anything else, but a few of them made life
quite difficult:

The importer API was built around file paths rather than URLs, and was tightly
coupled to the physical filesystem. This made it impossible to override all
file-based loads and present a fully virtual filesystem, and caused custom
Node importers to interact poorly with the new module system.
The function API was built around mutable value objects, which runs counter to
Sass’s immutable nature. It also provided no utility methods (such as looking
up a key in a map) to make it easier to implement idiomatic custom functions,
and didn’t provide access to crucial information about values such as whether
strings were quoted.
All of the asynchronous functions were callback-based rather than
promise-based.
The new API addresses these issues and more with a modern, idiomatic API that
will make working with Sass from JS a breeze.


Compilation permalinkCompilation

At the heart of the API are four functions that do the actual Sass compilation,
two synchronous and two asynchronous. They’re presented here in TypeScript
syntax to clarify exactly what they take and return, but you can always call
them from plain JS:
function compile(
path: string,
options?: Options<'sync'>
): CompileResult;

function compileString(
source: string,
options?: StringOptions<'sync'>
): CompileResult;

function compileAsync(
path: string,
options?: Options<'async'>
): Promise<CompileResult>;

function compileStringAsync(
source: string,
options?: StringOptions<'async'>
): Promise<CompileResult>;


The compile() and compileAsync() functions load a Sass file from a path on
disk, whereas compileString() and compileStringAsync() compile Sass source
code passed in as a string. All these take the following options:

alertAscii: Whether errors and warnings should use only ASCII characters (as
opposed to, for example, Unicode box-drawing characters).
alertColor: Whether errors and warnings should use terminal colors.
loadPaths: A list of file paths to use to look up files to load, just like
includePaths in the old API.
importers: A list of custom importers to use to load Sass
source files.
functions: An object whose keys are Sass function signatures and whose
values are custom functions.
quietDeps: Whether to silence deprecation warnings in dependencies.
logger: The custom logger to use to emit warnings and debug
messages.
sourceMap: Whether to generate a source map during compilation.
style: The output style, 'compressed' or 'expanded'.
verbose: Whether to emit every deprecation warning encountered.
The compileString() and compileStringAsync() functions take a few additional
options:

syntax: The syntax of the file, 'scss' (the default), 'indented', or
'css'.
url: The canonical URL of the file.
importer: The custom importer to treat as the file’s source.
If this is passed, this importer will be used to resolve relative loads from
this stylesheet.
All these functions return an object with the following fields:

css: The compiled CSS, as a string.
loadedUrls: All the URLs loaded during the compilation, in no particular
order.
sourceMap: The source map for the file if sourceMap: true was passed, as
a decoded object.
As with the Node Sass API, the synchronous functions will be substantially
faster than their asynchronous counterparts. Unfortunately the new API will not
support the fibers option for speeding up asynchronous compilation, since the
fibers package has been discontinued.


Loggers permalinkLoggers

The logger API gives you more fine-grained control over how and when warnings
and debug messages are emitted. Unlike other aspects of this proposal, a
logger option will also be added to the old API to allow you to control your
messages there without needing to upgrade to the new API immediately.

A logger implements the following interface:
interface Logger {
warn?(
message: string,
options: {
deprecation: boolean;
span?: SourceSpan;
stack?: string;
}
): void;

debug?(
message: string,
options: {span: SourceSpan}
): void;
}


The warn function handles warnings, including both warnings from the compiler
itself and from @warn rules. It’s passed:

The warning message
A flag indicating whether it’s specifically a deprecation warning
A span indicating where the warning was located, if it comes from a specific
location
The Sass stack trace at the point at which the warning was encountered, if it
was encountered during execution
The debug function handles only @debug rules, and is just passed the message
and the rule’s span. For more information on the SourceSpan type, see the
Logger proposal.

Sass will also provide a built-in logger, Logger.silent, that never emits any
messages. This will allow you to easily run Sass in “quiet mode” where no
warnings are ever surfaced.


Importers permalinkImporters

Rather than modeling importers as single-function callbacks, the new API models
them as objects that expose two methods: one that canonicalizes a URL, and one
that loads a canonical URL.
// Importers for compileAsync() and compileStringAsync() are the same, except
// they may return Promises as well.
interface Importer {
canonicalize(
url: string,
options: {fromImport: boolean}
): URL | null;

load(canonicalUrl: URL): ImporterResult | null;
}


Note that even stylesheets that are loaded directly from the filesystem through
compile() or loadPaths are treated as though they’re loaded by an importer.
This built-in filesystem importer canonicalizes all paths to file: URLs, and
loads those URLs from the physical filesystem.


Canonicalizing permalinkCanonicalizing

The first step determines the canonical URL for a stylesheet. Each stylesheet
has exactly one canonical URL that in turn refers to exactly one stylesheet. The
canonical URL must be absolute, including a scheme, but the specific structure
is up to the importer. In most cases, the stylesheet in question will exist on
disk and the importer will just return a file: URL for it.

The canonicalize() method takes a URL string that may be either relative or
absolute. If the importer recognizes that URL, it returns a corresponding
absolute URL (including a scheme). This is the canonical URL for the
stylesheet in question. Although the input URL may omit a file extension or
an initial underscore, the canonical URL must be fully resolved.

For a stylesheet that’s loaded from the filesystem, the canonical URL will be
the absolute file: URL of the physical file on disk. If it’s generated
in-memory, the importer should choose a custom URL scheme to guarantee that
its canonical URLs don’t conflict with any other importer’s.

For example, if you’re loading Sass files from a database, you might use the
scheme db:. The canonical URL for a stylesheet associated with key styles
in the database might be db:styles.

This function also takes a fromImport option that indicates whether the
importer is being invoked from an @import rule (as opposed to @use,
@forward, or meta.load-css()).

Having a canonical URL for each stylesheet allows Sass to ensure that the
same stylesheet isn’t loaded multiple times in the new module system.


Canonicalizing Relative Loads permalinkCanonicalizing Relative Loads

When a stylesheet tries to load a relative URL, such as @use "variables", it’s
not clear from the document itself whether that refers to a file that exists
relative to the stylesheet or to another importer or load path. Here’s how the
importer API resolves that ambiguity:

First, the relative URL is resolved relative to the canonical URL of the
stylesheet that contained the @use (or @forward or @import). For
example, if the canonical URL is file:///path/to/my/_styles.scss, then the
resolved URL will be file:///path/to/my/variables.
This URL is then passed to the canonicalize() method of the importer that
loaded the old stylesheet. (That means it’s important for your importers to
support absolute URLs!) If the importer recognizes it, it returns the
canonical value which is then passed to that importer’s load(); otherwise,
it returns null.
If the old stylesheet’s importer didn’t recognize the URL, it’s passed to all
the importers‘ canonicalize functions in the order they appear in options,
then checked for in all the loadPaths. If none of those recognizes it, the
load fails.
It’s important that local relative paths take precedence over other importers or
load paths, because otherwise your local stylesheets could get unexpectedly
broken by a dependency adding a file with a conflicting name.


Loading permalinkLoading

The second step actually loads the text of the stylesheet. The load()
method takes a canonical URL that was returned by canonicalize() and
returns the contents of the stylesheet at that URL. This is only called once
per compilation for each canonical URL; future loads of the same URL will
re-use either the existing module (for @use and @forward) or the parse
tree (for @import).

The load() method returns an object with the following fields:

css: The text of the loaded stylesheet.
syntax: The syntax of the file: 'scss', 'indented', or 'css'.
sourceMapUrl: An optional browser-accessible URL to include in source maps
when referring to this file.

FileImporter permalinkFileImporter


This proposal also adds a special type of importer known as a FileImporter.
This importer makes the common case of redirecting loads to somewhere on the
physical filesystem easier. It doesn’t require the caller to implement
load(), since that’s always going to be the same for files on disk.
interface FileImporter {
findFileUrl(
url: string,
options: {fromImport: boolean}
): FileImporterResult | null;
}


The findFileUrl() method takes a relative URL and returns an object with the
following fields:

url: The absolute file: URL of the file to load. This URL doesn’t need to
be fully canonicalized: the Sass compiler will take care of resolving
partials, file extensions, index files, and so on.
sourceMapUrl: An optional browser-accessible URL to include in source maps
when referring to this file.

Functions permalinkFunctions

The new function API’s function type is very similar to the old API’s:
type CustomFunctionCallback = (args: Value[]) => Value;


The only differences are:

Async functions return a Promise<Value> rather than calling a callback.
The value types themselves are different.
The second point is pretty substantial, though! The new value types are much
more fleshed out than the old versions. Let’s start with the parent class:
abstract class Value {
/**
* Returns the values of `this` when interpreted as a list.
*
* - For a list, this returns its elements.
* - For a map, this returns each of its key/value pairs as a `SassList`.
* - For any other value, this returns a list that contains only that value.
*/
get asList(): List<Value>;

/** Whether `this` is a bracketed Sass list. */
get hasBrackets(): boolean;

/** Whether `this` is truthy (any value other than `null` or `false`). */
get isTruthy(): boolean;

/** Returns JS's null if this is `sassNull`, or `this` otherwise. */
get realNull(): null | Value;

/** If `this` is a list, return its separator. Otherwise, return `null`. */
get separator(): ListSeparator;

/**
* Converts the Sass index `sassIndex` to a JS index into the array returned
* by `asList`.
*
* Sass indices start counting at 1, and may be negative in order to index
* from the end of the list.
*/
sassIndexToListIndex(sassIndex: Value): number;

/**
* Returns `this` if it's a `SassBoolean`, and throws an error otherwise.
*
* The `name` parameter is used for error reporting. It should match the name
* of a parameter passed to the custom function (without the `$`).
*/
assertBoolean(name?: string): SassBoolean;

/**
* Returns `this` if it's a `SassColor`, and throws an error otherwise.
*
* The `name` parameter is used for error reporting. It should match the name
* of a parameter passed to the custom function (without the `$`).
*/
assertColor(name?: string): SassColor;

/**
* Returns `this` if it's a `SassFunction`, and throws an error otherwise.
*
* The `name` parameter is used for error reporting. It should match the name
* of the parameter passed to the custom function (without the `$`).
*/
assertFunction(name?: string): SassFunction;

/**
* Returns `this` if it's a `SassMap` (or converts it to a `SassMap` if it's
* an empty list), and throws an error otherwise.
*
* The `name` parameter is used for error reporting. It should match the name
* of the parameter passed to the custom function (without the `$`).
*/
assertMap(name?: string): SassMap;

/**
* Returns `this` if it's a `SassNumber`, and throws an error otherwise.
*
* The `name` parameter is used for error reporting. It should match the name
* of a parameter passed to the custom function (without the `$`).
*/
assertNumber(name?: string): SassNumber;

/**
* Returns `this` if it's a `SassString`, and throws an error otherwise.
*
* The `name` parameter is used for error reporting. It should match the name
* of a parameter passed to the custom function (without the `$`).
*/
assertString(name?: string): SassString;

/**
* Returns the value of `this` if it can be interpreted as a map.
*
* - If this is a map, returns its contents.
* - If this is an empty list, returns an empty map.
* - Otherwise, returns `null`.
*/
tryMap(): OrderedMap<Value, Value> | null;

/** Returns whether `this == other` in SassScript. */
equals(other: Value): boolean;
}


There are a couple important things to note here:

Because CSS doesn’t have a strong syntactic differentiation between a single
element and a list containing one element, any Sass value may be treated as
though it’s a list. The Value makes it easy to follow this convention by
making the asList(), hasBrackets(), and separator() getters available
for every Value.
The list returned this was and the map returned by asMap() are immutable
types from the immutable package. This reflects Sass’s built-in
immutability of all its types. Although these values can’t be modified
directly, their APIs make it easy and efficient to create new values with
changes applied.
Sass’s list-indexing conventions are different than JavaScript’s. The
sassIndexToListIndex() function makes it easy to convert from Sass index to
JS index.
In Sass, any value may be used in a boolean context, with false
and null counting as “falsey” values. The isTruthy getter makes this
convention easy to follow.
The assert*() functions make it easy to ensure that you’re being passed the
arguments you expect, and to throw an idiomatic error if you’re not. They’re
particularly useful for TypeScript users since they’ll automatically narrow
the type of the Value.
Most Sass values have their own subclasses, but there are three singleton values
that are just available as constants: sassTrue, sassFalse, and sassNull
represent Sass’s true, false, and null values respectively.


Colors permalinkColors

The new API’s SassColor class provides access to colors in RGB, HSL, and HWB
format. As with built-in Sass color functions, any attribute can be accessed on
any color regardless of how it was initially created.
class SassColor extends Value {
/** Creates an RGB color. */
static rgb(
red: number,
green: number,
blue: number,
alpha?: number
): SassColor;

/** Creates an HSL color. */
static hsl(
hue: number,
saturation: number,
lightness: number,
alpha?: number
): SassColor;

/** Creates an HWB color. */
static hwb(
hue: number,
whiteness: number,
blackness: number,
alpha?: number
): SassColor;

/** The color's red channel. */
get red(): number;

/** The color's green channel. */
get green(): number;

/** The color's blue channel. */
get blue(): number;

/** The color's hue. */
get hue(): number;

/** The color's saturation. */
get saturation(): number;

/** The color's lightness. */
get lightness(): number;

/** The color's whiteness. */
get whiteness(): number;

/** The color's blackeness. */
get blackness(): number;

/** The color's alpha channel. */
get alpha(): number;

/**
* Returns a copy of `this` with the RGB channels updated to match `options`.
*/
changeRgb(options: {
red?: number;
green?: number;
blue?: number;
alpha?: number;
}): SassColor;

/**
* Returns a copy of `this` with the HSL values updated to match `options`.
*/
changeHsl(options: {
hue?: number;
saturation?: number;
lightness?: number;
alpha?: number;
}): SassColor;

/**
* Returns a copy of `this` with the HWB values updated to match `options`.
*/
changeHwb(options: {
hue?: number;
whiteness?: number;
blackness?: number;
alpha?: number;
}): SassColor;

/** Returns a copy of `this` with `alpha` as its alpha channel. */
changeAlpha(alpha: number): SassColor;
}



Numbers permalinkNumbers

The SassNumber class stores its numerator and denominator units as arrays
rather than strings. In addition, it provides methods for asserting that it has
specific units (assertNoUnits(), assertUnit()) and for converting it to
specific units (convert(), convertToMatch(), convertValue(),
convertValueToMatch(), coerce(), coerceValue(), coerceValueToMatch()).

Sass’s numeric logic is also subtly different from JS, since Sass considers
numbers that differ by less than the 10th decimal digit to be identical. This
API provides a number of methods that help convert between this and JavaScript’s
numeric logic.
class SassNumber extends Value {
/** Creates a Sass number with no units or a single numerator unit. */
constructor(value: number, unit?: string);

/** Creates a Sass number with multiple numerator and/or denominator units. */
static withUnits(
value: number,
options?: {
numeratorUnits?: string[] | List<string>;
denominatorUnits?: string[] | List<string>;
}
): SassNumber;

/** This number's value. */
get value(): number;

/**
* Whether `value` is an integer according to Sass's numeric logic.
*
* The integer value can be accessed using `asInt`.
*/
get isInt(): boolean;

/**
* If `value` is an integer according to Sass's numeric logic, returns the
* corresponding JS integer, or `null` if `value` isn't an integer.
*/
get asInt(): number | null;

/** This number's numerator units. */
get numeratorUnits(): List<string>;

/** This number's denominator units. */
get denominatorUnits(): List<string>;

/** Whether `this` has numerator or denominator units. */
get hasUnits(): boolean;

/**
* If `value` is an integer according to Sass's numeric logic, returns the
* corresponding JS integer, or throws an error if `value` isn't an integer.
*
* The `name` parameter is used for error reporting. It should match the name
* of the parameter passed to the custom function (without the `$`).
*/
assertInt(name?: string): number;

/**
* If `value` is between `min` and `max` according to Sass's numeric logic,
* returns it clamped to that range. Otherwise, throws an error.
*
* The `name` parameter is used for error reporting. It should match the name
* of the parameter passed to the custom function (without the `$`).
*/
assertInRange(min: number, max: number, name?: string): number;

/**
* Returns `this` if it has no units. Otherwise, throws an error.
*
* The `name` parameter is used for error reporting. It should match the name
* of a parameter passed to the custom function (without the `$`).
*/
assertNoUnits(name?: string): SassNumber;

/**
* Returns `this` if it has `unit` as its single (numerator) unit. Otherwise,
* throws an error.
*
* The `name` parameter is used for error reporting. It should match the name
* of a parameter passed to the custom function (without the `$`).
*/
assertUnit(name?: stringunit: string): SassNumber;

/** Returns whether `this` has the single numerator unit `unit`. */
hasUnit(unit: string): boolean;

/** Returns whether this number's units are compatible with `unit`. */
compatibleWithUnit(unit: string): boolean;

/**
* If this number's units are compatible with `newNumerators` and
* `newDenominators`, returns a new number with those units that's equal to
* `this`. Otherwise, throws an error.
*
* Note that unitless numbers are only compatible with other unitless numbers.
*/
convert(
newNumerators: string[] | List<string>,
newDenominators: string[] | List<string>
): SassNumber;

/**
* If this number's units are compatible with `other`'s, returns a new number
* with `other`'s units that's equal to `this`. Otherwise, throws an error.
*
* Note that unitless numbers are only compatible with other unitless numbers.
*/
convertToMatch(other: SassNumber): SassNumber;

/** Equivalent to `convert(newNumerators, newDenominators).value`. */
convertValue(
newNumerators: string[] | List<string>,
newDenominators: string[] | List<string>
): number;

/** Equivalent to `convertToMatch(other).value`. */
convertValueToMatch(other: SassNumber): number;

/**
* Like `convert()`, but if `this` is unitless returns a copy of it with the
* same value and the given units.
*/
coerce(
newNumerators: string[] | List<string>,
newDenominators: string[] | List<string>
): SassNumber;

/**
* Like `convertToMatch()`, but if `this` is unitless returns a copy of it
* with the same value and `other`'s units.
*/
coerceToMatch(other: SassNumber): SassNumber;

/** Equivalent to `coerce(newNumerators, newDenominators).value`. */
coerceValue(
newNumerators: string[] | List<string>,
newDenominators: string[] | List<string>
): number;

/** Equivalent to `coerceToMatch(other).value`. */
coerceValueToMatch(other: SassNumber): number;
}



Strings permalinkStrings

The SassString class provides access to information about whether or not the
string is quoted. As with lists, JS’s notion of indexes differs from Sass’s, so
it also provides the sassIndexToStringIndex() method to convert a JS index
into a Sass index.
class SassString extends Value {
/** Creates a string with the given `text`. */
constructor(
text: string,
options?: {
/** @default true */
quotes: boolean;
}
);

/** Creates an empty string`. */
static empty(options?: {
/** @default true */
quotes: boolean;
}): SassString;

/** The contents of `this`. */
get text(): string;

/** Whether `this` has quotes. */
get hasQuotes(): boolean;

/** The number of Unicode code points in `text`. */
get sassLength(): number;

/**
* Converts the Sass index `sassIndex` to a JS index into `text`.
*
* Sass indices start counting at 1, and may be negative in order to index
* from the end of the list. In addition, Sass indexes strings by Unicode code
* point, while JS indexes them by UTF-16 code unit.
*/
sassIndexToStringIndex(sassIndex: Value): number;
}



Lists permalinkLists

As mentioned above, most list functions are on the Value superclass to make it
easy to follow the Sass convention of treating all values as lists. However, the
SassList class can still be constructed to make new lists:
class SassList extends Value {
/** Creates a Sass list with the given `contents`. */
constructor(
contents: Value[] | List<Value>,
options?: {
/** @default ',' */
separator?: ListSeparator;
/** @default false */
brackets?: boolean;
}
);

/** Creates an empty Sass list. */
static empty(options?: {
/** @default null */
separator?: ListSeparator;
/** @default false */
brackets?: boolean;
}): SassList;
}



Maps permalinkMaps

The SassMap class simply exposes its contents as an OrderedMap from the
immutable package.
class SassMap extends Value {
/** Creates a Sass map with the given `contents`. */
constructor(contents: OrderedMap<Value, Value>);

/** Creates an empty Sass map. */
static empty(): SassMap;

/** Returns this map's contents. */
get contents(): OrderedMap<Value, Value>;
}



Functions permalinkFunctions

The SassFunction class is fairly restrictive: it just allows a new first-class
function to be created with a synchronous callback. These functions can’t be
invoked by custom functions—but they still provide more power than the old API!
class SassFunction extends Value {
/**
* Creates a Sass function value with the given `signature` that calls
* `callback` when it's invoked.
*/
constructor(
signature: string,
callback: CustomFunctionCallback
);
}



More Information permalinkMore Information

If you want to know more about these proposals and see their most up-to-date
forms, they’re available on GitHub to view in full:

Compile API proposal
Logger proposal
Importer proposal
Functions and values proposal
We’re eager for feedback, so please let us know what you think! The proposals
in question will be open for at least a month after this blog post goes live,
and possibly more depending on how lively the discussion around them is.

How To Create Your First Shopify Theme Section


Giving your clients creative control is key, especially when they want the ability to customize their store. Shopify’s Online Store 2.0 unlocks powerful tools for personalizing a site.
In this article, we’ll cover how to get started with creating diff...

The History Of The Shopping Cart


The story of the shopping cart’s rise to ubiquity is filled with light-bulb ideas, artistic interpretations, and even a well-known psychological theory on social behavior.More

Edit Your C++ Code While Debugging With Hot Reload In Visual Studio 2022

Hot Reload support for C++ Applications

In Visual Studio 2022 Preview 2, we are happy to announce that Hot Reload is now supported for C++.

Hot Reload for C++, powered by Edit and Continue, is a new way of editing your code while actively debugging.
The post Edit Your C++ Code while Debugging with Hot Reload in Visual Studio 2022 appeared first on C++ Team Blog.